我正在阅读Joshua Bloch关于“覆盖equals()方法”的在线章节。 这是link。 以下部分让我感到困惑,
反身性 - 第一个要求仅仅指对象必须 等于自己。很难想象违反这一要求 无意的。如果你违反了它,然后添加一个实例 你的类到集合,集合的包含方法会 几乎可以肯定地说集合中没有包含实例 你刚才添加的。
问题 - 集合的contains方法是否有可能在添加到它的实例上返回false?
我试过但返回的结果总是如此。
答案 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));
}
}