为什么ArrayList不会覆盖equals()以获得更好的性能?

时间:2016-02-22 08:42:09

标签: java arraylist

ArrayList从其父类equals继承AbstractList实现,这不是很有效。

首先可以检查两个ArrayLists的大小,如果这些大小不同,则立即返回false。为什么ArrayList没有这样做?

2 个答案:

答案 0 :(得分:7)

正如this answer中所述,这没有完成,因为某些实现的size方法具有O(n)复杂性,所以这确实是降级。 / p>

我同意在所有列表实现中使equals一致可以影响具有O(1)大小复杂度的集合,但也许Java开发人员认为当你使用它时,更容易插入它需要而不是删除它(你将不得不重新实现整个方法!)。例如,您可以使用以下内容轻松添加此优化:

public boolean equals(Object o) {
    // here it is
    if (o instanceof List && this.size() != ((List)o).size())
        return false;

    // call the parent equals
    return super.equals(o);

但如果最初使用大小检查(在抽象类中)实现,则必须重新实现整个方法并删除大小检查:

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;

    ListIterator<E> e1 = listIterator();
    ListIterator<?> e2 = ((List<?>) o).listIterator();
    while (e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }
    return !(e1.hasNext() || e2.hasNext());
}

答案 1 :(得分:1)

最后,决定覆盖ArrayList.equals()ArrayList.indexOf()https://bugs.openjdk.java.net/browse/JDK-8196340。基准测试显示了明显的性能提升。