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

Sat*_*tya 11 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我在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);
Run Code Online (Sandbox Code Playgroud)

根据equality子句,对象是相同且相等的,但HashSet将包含重复项.

是否有任何违反wrt equals或hashcode的事件?如果这段代码完全没问题,那么有什么方法可以防止添加重复项?

我假设,在确定equals和hashcode时使用的任何字段应该是immutabe?

NPE*_*NPE 18

我假设,在确定equals和hashcode时使用的字段应该是不可变的吗?

那就对了.

更确切地说,您的问题中的代码违反了Set合同的以下部分:

注意:如果将可变对象用作set元素,则必须非常小心.如果在对象是集合中的元素的同时以影响等于比较的方式更改对象的值,则不指定集合的​​行为.这种禁令的一个特例是,不允许集合将自身作为一个要素包含在内.

一旦违反合同,所有投注都将被取消.

  • 也就是说,在调用"add"时会发生重复检查,如[Javadoc]中所述(http://docs.oracle.com/javase/6/docs/api/java/util/Set.html#添加(E)).`add(e)`如果`e`不在集合中并且已经被添加,则返回`true`,如果已经在集合中,则返回`false`. (2认同)