Collection的contains方法是否会为添加到其中的实例返回false?

时间:2013-01-05 16:23:29

标签: java collections

我正在阅读Joshua Bloch关于“覆盖equals()方法”的在线章节。 这是link。 以下部分让我感到困惑,

  

反身性 - 第一个要求仅仅指对象必须   等于自己。很难想象违反这一要求   无意的。如果你违反了它,然后添加一个实例   你的类到集合,集合的包含方法会   几乎可以肯定地说集合中没有包含实例   你刚才添加的。

问题 - 集合的contains方法是否有可能在添加到它的实例上返回false?

我试过但返回的结果总是如此。

3 个答案:

答案 0 :(得分:1)

  

问题 - 集合的contains方法是否有可能在添加到它的实例上返回false?

除非添加的对象的equals()违反了合同,否则正如书中引用的那样解释。

根据@Karthik T的建议,尝试使用equals()无条件返回false的对象(从而违反合同)。

答案 1 :(得分:1)

为了说明这一点,请使用这个简单的类:

class C {
    private int i;
    public C(int i) { this.i = i; }
}

现在,如果你这样做:

C c1 = new C(1);
C c2 = new C(1);

List<C> l = new ArrayList<C>();

l.add(c1);

l.contains(c2)将返回false,因为c2.equals(c1)false,尽管两个实例都具有相同的构造函数参数。

这是因为课程C不会覆盖.equals().hashCode()

一般情况下,每次你的类必须在任何类型的Collection中使用时,你最好覆盖这两种方法。在这种情况下:

// Note: final class, final member -- that makes this class immutable
final class C {
    private final int i;
    public C(int i) { this.i = i; }

    @Override
    public int hashCode() { return i; }
    @Override
    public boolean equals(Object o)
    {
        // no object equals null
        if (o == null)
            return false;
        // an object is always equal to itself
        if (this == o)
            return true;
        // immutable class: if the class of the other is not the same,
        // objects are not equal
        if (getClass() != o.getClass())
            return false;
        // Both objects are of the same class: check their members
        return i == ((C) o).i;
    }
}

答案 2 :(得分:0)

这是一个集合的contains方法的演示,该方法为刚刚添加到集合中的对象返回false。我使用Eclipse生成的正常equals和hashCode,并将equals方法更改为非反身。具体来说,它在将对象与自身进行比较时返回false。

import java.util.LinkedList;
import java.util.List;

public class Test {
  int someValue;
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + someValue;
    return result;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      // Bad. Non-reflexive. Should return true.
      return false;
    }
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Test other = (Test) obj;
    if (someValue != other.someValue)
      return false;
    return true;
  }
  public static void main(String[] args) {
    List<Test> myList = new LinkedList<Test>();
    Test myObject = new Test();
    myList.add(myObject);
    System.out.println(myList.contains(myObject));
  }
}