Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java集合中的contains()/indexOf()使用o.equals(e)而不是e.equals(o)?_Java_Collections_Equals - Fatal编程技术网

为什么Java集合中的contains()/indexOf()使用o.equals(e)而不是e.equals(o)?

为什么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

为什么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.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
whyle
x.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是字符串而元素不是,那么即使元素重写了等号,也找不到元素:\n
e
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; }