16

奇怪的是,默认的 JDK 6 实现AbstractList::equals() 似乎并没有首先检查两个列表是否具有相同的大小

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());
}

如果两个列表都包含很多项目,或者比较需要时间的项目,它会在意识到一个列表比另一个列表短之前将它们全部比较;在我看来,这确实效率低下,因为甚至可以在不调用比较的情况下进行相等。

尤其是在很多情况下,列表大小在大多数情况下都会有所不同。此外,大多数 JavaList实现都具有 O(1)size()性能(甚至是 LinkedList,它将其大小保留在缓存中)。

这种默认实现有充分的理由吗?

4

1 回答 1

12

equals 方法的操作有一些详细说明,它需要 O(n) 行为。虽然这对于 size 方法为 O(1) 的子类可能不是最理想的,但对于某些子类,size 方法本身可能为 O(n) 并且请求的行为实际上是降级。无论如何,规范是明确的,并且无法进行此更改。

请注意,如果需要,子类可以覆盖 equals,并在适当时插入大小比较。

参考。

于 2013-09-23T11:32:48.790 回答