我对Efective Java这本书有所怀疑.怀疑是关于equals方法
反身规则违反.这本书说如下:
" 如果你违反了它,然后将你的类的一个实例添加到一个集合中,那么集合的contains方法肯定会说该集合不包含你刚刚添加的实例. "
为了测试它,我写了一个示例类,但contains方法没有返回false它返回true.谁能说出问题是什么?
我同意这个程序的结果确实令人费解:
import java.util.*;
class Item {
@Override
public boolean equals(Object obj) {
return false; // not even equal to itself.
}
}
class Test {
public static void main(String[] args) {
Collection<Item> items = new HashSet<Item>();
Item i = new Item();
items.add(i);
System.out.println(items.contains(i)); // Prints true!
}
}
Run Code Online (Sandbox Code Playgroud)
答案是在contains执行argument == object之前执行检查argument.equals(object).从结果contains是true,因为item == item持有,即使item.equals(item)返回false.
假设equals遵循其合同(反身),这种实施方式contains是正确的.
如果你仔细阅读了你发布的引用,那么作者就会包含" 几乎 " 这个词 :)你似乎偶然发现了该规则的少数例外情况之一.
其他集合(ArrayList例如)equals直接使用,如果在上面的程序中更改new HashSet<Item>()为new ArrayList<Item>(),则按false预期打印.
反身手段x.equals(x)应该回来true
class Foo {
int i;
public boolean equals(Object obj) {
return ((Foo) obj).i < this.i;
}
}
Run Code Online (Sandbox Code Playgroud)
这将返回false。当您将其放入列表并调用list.contains(foo)它时,它将返回false,因为列表中的所有元素都不等于您传递的元素。之所以这样,是因为list.contains(..)对元素进行了迭代,并对每个元素进行检查if (elem.equals(arg))
请参阅的文档 Collection.contains(..)
| 归档时间: |
|
| 查看次数: |
1720 次 |
| 最近记录: |