Java集合不包含以前的put元素

Java集合不包含以前的put元素,java,hashset,Java,Hashset,在我们的应用程序中,我经常看到生成的equals和hashCode方法。 我不知道为什么它们会被覆盖,但是我担心它们会被生成(我认为是这样的,因为它们非常相似)。下面的示例显示了该问题。创建一个SomeBean instance,它首先存在,然后集合不包含此对象。这是因为“a”值和hashcode的更改已更改。 哈希集缓存哈希代码?那么,以前放入哈希集中的对象的每次更改都是危险的 private class SomeBean{ private Integer a = 0; pub

在我们的应用程序中,我经常看到生成的equals和hashCode方法。 我不知道为什么它们会被覆盖,但是我担心它们会被生成(我认为是这样的,因为它们非常相似)。下面的示例显示了该问题。创建一个SomeBean instance,它首先存在,然后集合不包含此对象。这是因为“a”值和hashcode的更改已更改。 哈希集缓存哈希代码?那么,以前放入哈希集中的对象的每次更改都是危险的

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));;

}

但现在我冒着“a”=0的对象和“a”=0创建并随后更改的其他每个新对象都是相同的对象的风险。

它不会工作。原因是HashSet是基于这样一种假设,即对象的哈希代码不会更改,但您会更改对象的值:

sb.setA(4);
这会更改哈希代码的值


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

它不会工作。原因是HashSet是基于这样一种假设,即对象的哈希代码不会更改,但您会更改对象的值:

sb.setA(4);
这会更改哈希代码的值


内部哈希映射基于数组。散列代码用于选择用于散列映射实现的数组中的位置,并且由于散列代码从一个调用更改为另一个调用,所以散列集正在查看数组中的不同位置。由于数组中的另一个元素是空的,HashSet假设数据结构中不存在该元素。

请提供代码的输出(添加重复项或未找到现有对象:相同的想法)。请提供代码的输出(添加重复项或未找到现有对象:相同的想法)