为什么Java集合中的contains()/indexOf()使用o.equals(e)而不是e.equals(o)?
为什么Java集合框架中的方法和使用为什么Java集合中的contains()/indexOf()使用o.equals(e)而不是e.equals(o)?,java,collections,equals,Java,Collections,Equals,为什么Java集合框架中的方法和使用o.equals(e)而不是e.equals(o)(其中o是方法的参数,e是集合中的元素) 有人知道这其中的原因吗?因为o不是空的,但是e不一定是空的。以链接列表的代码为例: for (Entry e = header.next; e != header; e = e.next) { if (o.equals(e.element)) return index; index++; } 在本例中,这样做可以避免集合中每个项的e.e
o.equals(e)
而不是e.equals(o)
(其中o
是方法的参数,e
是集合中的元素)
有人知道这其中的原因吗?因为
o
不是空的,但是e
不一定是空的。以链接列表的代码为例:
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++;
}
}
使用x.equals(y)
和y.equals(x)
之间的区别如下:
如果x
为null
,y.equals(x)
将简单地返回false
whylex.equals(y)
将导致空点异常。假设您有一个友好对象的集合,例如
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) );
如果包含名为e.equals(o)
的元素,那么您的邪恶计划将失败,因为集合中已有的友好元素将决定一个不友好的对象是否与它们相等。
通过调用o.equals(e)
它是传递给contains
的不友好对象,可以决定它想要等于什么,从而允许您使用方法重写功能
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
包含友好的?
是真的
,因为我们使用的是数组列表
;如果我们一直在使用HashSet
或任何散列方法,那么也有必要指定hashCode
方法
请注意,尽管的契约包含要求使用equals
方法,但有些实现可能不符合此要求,例如org.eclipse.emf.common.util.basicList
,让您自己去弄清楚这一点是在浪费时间
在这种情况下,你必须自己做比较
boolean contained = false;
for( Object e : c )
if( o.equals(e) ) { contained = true; break; }
你真的需要澄清这个问题。你所说的e
和0
是什么意思?请注意,API规范中出现的o.equals(e)
并不限制任何实现以这种方式实际实现它。他们只需要给出与该结果相同的答案。因为equals()在合同上要求是自反的,所以它们可以自由地在任意方向上实现它。。。处理等号的方式是逻辑的,因为O保证不为null,但是,这给我的代码带来了问题,因为如果O是字符串而元素不是,那么即使元素重写了等号,也找不到元素:\ne
和O
都可以null
(至少在某些集合中)。是的,但当你到达环路时,这已经得到了满足。这就是为什么我说o
已知不为空。我理解问题是关于方法的定义,而不是太多关于实现的问题,但回头看,也可能是相反的……David应该发布indexOf
的完整代码。您可以看到,o
在函数的该部分不能为null。Javadoc中定义方法的方式确保了equals()
永远不会用null
参数调用,也永远不会在null
引用中调用。文档如何确保我不会调用equals()
带有null
参数?
boolean contained = false;
for( Object e : c )
if( o.equals(e) ) { contained = true; break; }