为什么List.indexOf使用等于传入Object的方法?

时间:2014-03-06 21:08:04

标签: java

在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。这是唯一的原因吗?

4 个答案:

答案 0 :(得分:1)

ArrayList拥有它的方式,它避免了空检查。我没有看到任何其他原因。如果在elementData[i]上调用equals,则必须先检查每个元素是否为空。

现在,重要的一点是,在调用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。由于(在我们的示例中)oequals()对象,o需要知道列表中的每个项目是否相同,并且必须检查特定于{的值{1}}秒。当Cat返回true时,o将返回其所在的索引。

另一种可能有用的方法是考虑Cat如何检查相等性。对象本身只比较两个项的内存地址。它没有别的可以比较。即使对象真的是Cat.equals(Object other),如果List.indexOf(Object o)未被强制执行,也无法智能地比较两只狗。

答案 3 :(得分:-2)

对于对象,java指定.equals()方法,因为它们不能通过'=='直接比较。 在简单原始数据类型的情况下,可以使用'=='。 原始数据类型没有.equals()方法。