在Java中,为什么List<T>.indexOf(Object o)
方法使用参数的equals方法而不是<T>
的equals方法。
这是它的编码方式:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
这就是我期望它发挥作用的方式:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (elementData[i].equals(o))
return i;
}
return -1;
}
第二个for循环在完成第二种方法时需要做更多的空检查以避免任何NullPointerException。这是唯一的原因吗?
答案 0 :(得分:1)
ArrayList拥有它的方式,它避免了空检查。我没有看到任何其他原因。如果在elementData[i]
上调用equals,则必须先检查每个元素是否为空。
现在,重要的一点是,在调用equals的两种方式之间不应该有区别。
o
的实际类型确定的。这意味着,例如,如果传递indexOf
一个String,则调用String的重写equals方法,即使引用类型o
是Object。
对称:对于任何非空参考值 x 和 y , x.equals(y)应该返回 true 当且仅当 y.equals(x)返回 true 。
如果正确实现了equals方法,那么你调用它的对象将没有什么区别。
答案 1 :(得分:0)
问题“为什么”就是这样,只能由实施List
类的人来回答。我会说像路易斯;因为.equals
被指定为对称的,所以并不重要。合理的猜测是确保使用您提供的对象的.equals
实现。
但是,如果您希望更改其行为,则可以始终使用自己的实现覆盖它。
答案 2 :(得分:0)
这与继承有关。我们会说Object o
(参数)是Cat
对象的一个实例。 Cat
类以及其他所有类都是Object
的后代,因此Cat
必须具有Object
所有相同的公共方法。在Cat
中,我们还覆盖了由equals(Object other)
声明的Object
方法。 Cat
有自己的方式检查它是否等于另一个对象。如果没有,您将无法使用Cat
{/ 1}来自Dog
Apple
的{{1}} Carburetor
>
使用equals()
的{{1}}方法列出,或者更确切地说,您使用的List(可能是ArrayList)在其内容中标识Object o
。由于(在我们的示例中)o
是equals()
对象,o
需要知道列表中的每个项目是否相同,并且必须检查特定于{的值{1}}秒。当Cat
返回true时,o
将返回其所在的索引。
另一种可能有用的方法是考虑Cat
如何检查相等性。对象本身只比较两个项的内存地址。它没有别的可以比较。即使对象真的是Cat.equals(Object other)
,如果List.indexOf(Object o)
未被强制执行,也无法智能地比较两只狗。
答案 3 :(得分:-2)
对于对象,java指定.equals()方法,因为它们不能通过'=='直接比较。 在简单原始数据类型的情况下,可以使用'=='。 原始数据类型没有.equals()方法。