Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用自定义类作为键的Java HashSet:";包含();函数总是返回false_Java_Key_Equals_Hashset_Hashcode - Fatal编程技术网

使用自定义类作为键的Java HashSet:";包含();函数总是返回false

使用自定义类作为键的Java HashSet:";包含();函数总是返回false,java,key,equals,hashset,hashcode,Java,Key,Equals,Hashset,Hashcode,我尝试使用HashSet,同时使用我自己的类“Inner”作为键类型,如下所示: import java.util.HashSet; class Inner { int i; String s; public Inner(int i, String s) { this.i = i; this.s = s; } @Override public int hashCode() { return super

我尝试使用HashSet,同时使用我自己的类“Inner”作为键类型,如下所示:

import java.util.HashSet;
class Inner {
    int i;
    String s;
    public Inner(int i, String s) {
        this.i = i;
        this.s = s;
    }
    @Override
    public int hashCode() {
        return super.hashCode();
    }
    @Override
    public boolean equals(Object o) {
        Inner inner = (Inner) o;
        return i == inner.i && s.equals(inner.s);
    }
}

public class testEquals {
    public static void main(String [] args) {
        HashSet<Inner> hi = new HashSet<>();
        hi.add(new Inner(1,"abc"));
        System.out.println(hi.contains(new Inner(1,"abc")));
    }
}
import java.util.HashSet;
班级内部{
int i;
字符串s;
公共内部(整数i,字符串s){
这个。i=i;
这个.s=s;
}
@凌驾
公共int hashCode(){
返回super.hashCode();
}
@凌驾
公共布尔等于(对象o){
内部=(内部)o;
返回i==inner.i&&s.equals(inner.s);
}
}
公共类考试资格{
公共静态void main(字符串[]args){
HashSet hi=新的HashSet();
添加(新的内部(1,“abc”);
System.out.println(hi.contains(新的内部(1,“abc”)));
}
}
它打印“假”

(1) 我的问题是,只要我尝试使用“contains”函数,我就必须从“internal”类构造一个新对象来查询,但因为它是一个新对象,hashcode()就不同了。因此,对于“contains”函数,我总是得到一个“false”

(2) 如果我将hashCode()更改为在值相同时返回“true”like equals,那么在其他场景中,不同的对象引用被视为“==”就像一个唯一引用一样

(1) (2)似乎有冲突

如何解决这个问题


谢谢

您应该重写
hashCode
,使两个相等的对象具有相同的
hashCode

例如:

@Override
public int hashCode() {
    return Objects.hash(i,s);
}
我不知道你有什么问题。如果根据
equals()
两个对象相等,则
HashSet
应将它们视为相同的对象,即使它们不是

另一方面,如果希望
HashSet
将任何
内部
实例视为唯一的(无论其实例变量的值如何),只需不重写
hashCode
等于
。但是,在不重写这些方法的情况下使用
HashSet
很少有用

  • 您必须在不破坏equals-hashCode契约的情况下正确地重写
    hashCode()
  • equals()和hashCode()之间的约定是:

  • 如果两个对象相等,则它们必须具有相同的哈希代码
  • 如果两个对象具有相同的哈希代码,则它们可能相等,也可能不相等
  • hashCode()
    不返回true,它返回一个int值。因此,只要确保它为两个不同的对象返回相同的int值,
    equals()
    返回true