Java HashSet 使用自定义类作为键 : "contains()" function always return false

标签 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.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")));
    }
}

它打印“假”

(1) 我的问题是,只要我尝试使用“contains”函数,我就必须从“Inner”类构造一个新对象来查询,但是因为是一个新对象,hashcode() 是不同的。所以对于“包含”功能,我总是得到“假”。

(2) 如果我将 hashCode() 更改为在值相同时像等于一样返回“true”,那么在其他情况下,不同的对象引用将被视为“==”,就像一个唯一引用一样。

(1) 和 (2) 似乎有冲突。

如何解决?

谢谢!

最佳答案

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

例如:

@Override
public int hashCode() {
    return Objects.hash(i,s);
}

我不确定您对 (2) 有何疑问。如果根据 equals() 两个对象相等,则 HashSet 应将它们视为相同的对象,即使它们不是。

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

关于Java HashSet 使用自定义类作为键 : "contains()" function always return false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53723019/

相关文章:

python - 如何避免在 Python 中两次查找字典以获取/设置键值?

Java - 我们可以在不使用监听器的情况下检测是否按下了一个键吗?

git - 我从 .ssh 文件夹中删除了 known_hosts 文件,但无法 pull 入或推送 BitBucket 存储库

.net - 为什么使用 GetHashCode() 而不是 Equals()?

java - 是否可以检查 Point2D.Double 数组中的所有坐标?

java - 就处理能力和内存使用而言,使用局部变量相对于实例变量有什么好处,反之亦然

java - ListView不想刷新

java - Spring 测试MVC : How to use object as Request Parameters

java - 使用 .equals() 比较两个字符串不起作用

java - Facebook 没有获得除公开个人资料之外的任何权限