java - java.util.Set 什么时候检查重复项

标签 java set hashset

我有一个非常基本的问题,java.util.Set 什么时候检查添加的对象是否重复?

因为我有一个如下所示的模型类,它覆盖了 equals 和 hashcode 方法

public class SampleModel implements Comparable {
    private String name;

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

    // Setter and Getter omitted
    @Override
    public boolean equals(Object arg0) {
        boolean eq = false;

        if (arg0 instanceof SampleModel
                && this.name.equalsIgnoreCase(((SampleModel) arg0).name)) {
            eq = true;
        }
        return eq;
    }

    @Override
    public int compareTo(Object arg0) {
        return this.name.compareTo(((SampleModel) arg0).name);
    }

    @Override
    public int hashCode() {
        return this.name.length();
    }
}

这就是我在 HashSet 中使用模型对象的方式。

    SampleModel s1 = new SampleModel("Satya");
    SampleModel s2 = new SampleModel("Katti");

    Set<SampleModel> samSet = new HashSet<SampleModel>();
    System.out.println(samSet.add(s1));
    System.out.println(samSet.add(s2));

    s2.setName("Satya");
    System.out.println(s2.getName());
    System.out.println(s1 + ", " + s2);

根据相等子句,对象相同且相等,但 HashSet 将包含重复项。

equals 或 hashcode 是否有任何违规行为? 如果此代码完全正确,那么有什么方法可以防止添加重复项?

我假设,用于确定 equals 和 hashcode 的任何字段都应该不可变吗?

最佳答案

I assume, whatever fields used in determining equals and hashcode should be made immutable?

没错。

更准确地说,您问题中的代码违反了 Set 的以下部分契约(Contract):

Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

一旦你违反了契约(Contract),所有的赌注都会落空。

关于java - java.util.Set 什么时候检查重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10814824/

相关文章:

java - 观察服务 Java 7 轮询循环

Java BoxLayout 使用全宽

java - 用于比较数据集的任何 Java 集合

c# - 为什么在 Contains 期间不调用 GetHashCode?

java - 无法打印到文本文件

c++ - set::erase() 如何将 set::end 作为其参数?

c++ - std::set 迭代器自动 const

java - 如何构造动态类型的哈希表

java - Hashset 的 Hashcode 和 Equals

java - 从子类获取数据而不实例化