Java Set不包含先前放置的元素

0 java hashset

在我们的应用程序中,我经常看到生成的equals和hashCode方法.我不知道为什么他们被覆盖但是我担心它们是生成的(我认为它们非常相似).以下示例显示了该问题.一个SomeBean instnace被创建,它存在firlsty,然后该集合不包含这个对象.这是因为"a"值和哈希码的变化被改变了.HashSet缓存哈希码wright?因此,之前在Hashset中提出的目标的每次更改都是危险的吗?

private class SomeBean{
    private Integer a = 0;
    public void setA(Integer a) {
        this.a = a;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SomeBean someBean = (SomeBean) o;
        if (a != null ? !a.equals(someBean.a) : someBean.a != null) return false;
        return true;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + a.hashCode();
        return result;
    }
}
@Test
public void test() throws Exception {
    SomeBean sb = new SomeBean();
    Set set = new HashSet<>();
    set.add(sb);
    sb.hashCode();
   System.out.println( set.contains(sb));;
    sb.setA(4);
    System.out.println(set.contains(sb));;

}
Run Code Online (Sandbox Code Playgroud)

hashCode应该被SomeBean类缓存而且永远不会改变吗?它可能看起来像这样:

 @Override
    public int hashCode() {
        if (_hashCode == 0) {
            final int prime = 31;
            int result = 1;
            result = prime * result + a.hashCode();
            return result;
        } else return _hashCode;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是现在我冒了那个"a"= 0的对象和用"a"= 0创建的每个其他新对象然后改变的对象是相同的对象.

Iva*_*tyk 5

它不会起作用.原因是HashSet基于这样的假设:对象的哈希码不会改变,但是你改变了对象的值:

sb.setA(4);
Run Code Online (Sandbox Code Playgroud)

这会改变哈希码的值.

内部哈希映射基于数组.散列码用于选择数组中用于散列图实现的位置,并且因为散列码从一个调用更改为另一个HashSet正在查看数组中的不同位置.由于数组中的另一个元素是空的,HashSet假定数据结构中不存在这样的元素.