2

如果我们在 HashSet 中添加两个不同的对象(可变),然后通过调用 setter 更改对象的值(使它们相同),则 hashSet 的大小保持为 2

我无法理解相同的原因:

public static void main(String[] args) {
        Employee e = new Employee();
        e.setName("Amit");
        Employee e1 = new Employee();
        e1.setName("Jitender");
        Set<Person> hashSet = new HashSet<Person>();
        hashSet.add(e);
        hashSet.add(e1);
        // size of set is >>2
        System.out.println("size of set is >>" + hashSet.size());
        e1.setName("Amit");
        // updated size of set is >>2
        System.out.println("updated size of set is >>" + hashSet.size());
}

员工类是:

public class Employee extends Person {

    public Employee() {
    }

    public Employee(String name) {
        this.name = name;
    }

    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        Employee e = (Employee) obj;
        return this.name.equals(e.name);
    }
}
4

5 回答 5

3

HashSet不打算对它包含的对象的变化做出反应。事实上,文档警告不要将可变对象添加到集合中并修改它们。

Set界面文档

注意:如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的一个元素,则不指定集合的​​行为。此禁令的一个特殊情况是不允许集合包含自身作为元素。

(另一点是HashSet使用成员equals()hashCode()方法,这意味着如果您没有为您的 实现这些方法,除非它们是对同一对象的两个引用,否则Employee两个Employees 将不相等Employee。)在您的编辑中,您表明您实现了那。

在一个实际的“如果我这样做会发生什么?” 请注意,如果您查看(b/ca实现为将您插入的条目映射到虚拟对象的 a)的源代码,HashMap您可以看到大小仅在您添加和删除变量时更新,并且即使重新散列表以增加容量,没有相等性检查,因此您的重复对象将保留在您刚刚通过做您不应该做的事情而破坏的那个集合中。HashSetHashMap

于 2012-05-04T04:01:26.567 回答
3

你是如何定义类中的hashCode()equals()方法的Employee?此外,如果集合中的两个可变对象突然具有相同的哈希值,a 的合同中没有任何内容HashSet指定要做什么,您不能假设其中任何一个对象都会自动从集合中删除。

另外,请注意以下文档中的此注释Set

如果将可变对象用作集合元素,则必须非常小心。如果对象的值以影响等于比较的方式更改,而对象是集合中的一个元素,则不指定集合的​​行为。此禁令的一个特殊情况是不允许集合包含自身作为元素。

于 2012-05-04T04:02:39.963 回答
0

size()返回集合中的元素数。由于您不通过调用集合e1.setName()的大小来更改集合,因此保持不变。

于 2012-05-04T04:01:26.233 回答
0

您向集合中添加了 2 个不同的对象。即使它们的值相同,它们也是不同的对象。

于 2012-05-04T04:01:38.433 回答
0

它们是使用 Employee.class 的两个不同实例创建的。因此,即使它们具有相同的属性名称值,它们仍然是不同的对象。除非当然 hash 和 equals 在 Employee.class 中被覆盖,以便相等性基于属性名称。

于 2012-05-04T04:04:16.267 回答