为什么Java集合框架中的方法contains()
和indexOf()
使用o.equals(e)
而不是e.equals(o)
定义(其中o
是方法的参数并且e
是集合中的元素)?
有人知道原因吗?
答案 0 :(得分:16)
因为已知o
不为空,但e
不一定是。以LinkedList
:
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
在此示例中,以这种方式执行此操作可避免为集合中的每个项目保护e.element
为空。这是考虑o
为空的完整代码:
if (o == null) {
for (Entry e = header.next; e != header; e = e.next) {
if (e.element == null)
return index;
index++;
}
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
答案 1 :(得分:1)
使用x.equals(y)
和y.equals(x)
之间的区别如下:
如果x
为null
,则y.equals(x)
只会返回false
whyle x.equals(y)
会导致NullPointerException。
答案 2 :(得分:1)
假设您有一组友好对象,例如
class Friendly {
final int i;
Friendly( int i ) { this.i = i; }
public boolean equals( Object o ) {
return o != null && o instanceof Friendly && ((Friendly)o).i == this.i;
}
}
java.util.Collection c = new java.util.ArrayList();
for( int i = 0; i < 10; i++ )
c.add( new Friendly(i) );
并且您希望插入一个不友好的对象,contains
永远不会在集合中找到它:
class Unfriendly extends Friendly {
Unfriendly( int i ) { super(i); }
public boolean equals( Object o ) { return false; }
}
如果contains
调用e.equals(o)
,那么您的险恶计划将失败,因为集合中已有的友好元素决定是否不友好对象等于或不等。
通过调用o.equals(e)
,传递给contains
的不友好对象可以决定它想要的内容,允许您使用方法覆盖功能。< / p>
System.out.println("contains friendly? " + c.contains(new Friendly(1)));
#> contains friendly? true
System.out.println("contains unfriendly? " + c.contains(new Unfriendly(1)));
#> contains unfriendly? false
contains friendly?
为true
,因为我们正在使用ArrayList
;如果我们使用HashSet
或任何哈希值,则有必要指定hashCode
方法。
请注意,虽然contains
的合同要求使用equals
方法,但某些实现可能不符合此类,例如org.eclipse.emf.common.util.BasicEList
,因为您想到这一点而浪费时间进行。
在这种情况下,您必须自己进行比较,例如
boolean contained = false;
for( Object e : c )
if( o.equals(e) ) { contained = true; break; }