naskobg13
naskobg13

Reputation: 79

Why equals return false in this situation?

Here is the default JDK 8 implementation of 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());
}

I have following code :

public static void main(String[] args) {

        List list = new LinkedList<List>();
        List innerList = new LinkedList<List>();
        list.add(innerList);

        System.out.println(list.equals(innerList));
    }

In my opinion the two lists here are not equals and it should return false. And the compiler return false. My question is why? In the last line return !(e1.hasNext() || e2.hasNext());

e1.hasNext() is false and e2.hasNext() is false so overall it should return true. Why it return false ?

Upvotes: 2

Views: 117

Answers (2)

Itay Maman
Itay Maman

Reputation: 30723

actually this sentence

e1.hasNext() is false and e2.hasNext() is false ...

is incorrect. Here's why: e1 is the iterator over list and e2 is the iterator over innerList.

list contains one element (due to list.add(innerList)) so its iterator has one element to iterate over so e1.hasNext() is true. Hence e1.hasNext() || e2.hasNext() yields true, so !(e1.hasNext() || e2.hasNext()) evaluates to false.

Upvotes: 1

Eran
Eran

Reputation: 393811

Your code compares an empty List to a List with a single element, so of course equals would return false.

return !(e1.hasNext() || e2.hasNext()); evaluates to return !(true || false); (since one List is empty and the other is not) which evaluates to return !true, which is false.

Upvotes: 5

Related Questions