문제

Strangely the default JDK 6 implementation of AbstractList::equals() does not seems to check first if the two lists have the same size:

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

If both lists contains lots of items, or items taking time to compare, it will compare them all before realizing that one list is shorter than the other; which seems to me really inefficient as the equality could have been made without even calling one compare.

Especially that for lots of situations lists sizes would most of the time differ. Furthermore, most Java List implementations have O(1) size() performance (even LinkedList, which keep its size in cache).

Is there a good reason for this default implementation?

도움이 되었습니까?

해결책

The operation of the equals method is specified in some detail, and it requires the O(n) behavior. While this may be suboptimal for subclasses whose size method is O(1), for some subclasses the size method may itself be O(n) and the requested behavior would actually be a degradation. In any event the spec is clear and this change cannot be made.

Note that a subclass may override equals if desired, inserting a size comparison when appropriate.

Reference.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top