JDK implementation of AbstractList::equals() does not check for list size equality first

对着背影说爱祢 提交于 2019-12-23 06:57:17

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/18958113/jdk-implementation-of-abstractlistequals-does-not-check-for-list-size-equali

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!