Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 358
Laurent Grégoire Avatar asked Sep 23 '13 11:09

Laurent Grégoire


People also ask

How to check 2 lists are equal in java?

You can compare two array lists using the equals() method of the ArrayList class, this method accepts a list object as a parameter, compares it with the current object, in case of the match it returns true and if not it returns false.

How to compare a value in a list in java?

Java equals() method of List interface compares the specified object with the list for equality. It overrides the equals() method of Object class. This method accepts an object to be compared for equality with the list. It returns true if the specified object is equal to the list, else returns false.


1 Answers

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.

like image 156
Sajal Dutta Avatar answered Oct 24 '22 20:10

Sajal Dutta