hometown
hometown

Reputation: 279

How does Collections.unmodifiableCollection use equals method?

The unmodifiableCollection method (as well as thesynchronizedCollection and checkedCollectionmethods discussed later in this section) returns a collection whose equals method does not invoke the equals method of the underlying collection. Instead, it inherits the equals method of the Object class, which just tests whether the objects are identical. If you turn a set or list into just a collection, you can no longer test for equal contents. The view acts in this way because equality testing is not well defined at this level of the hierarchy. The views treat the hashCode method in the same way.However, the unmodifiableSet and unmodifiableList methods use the equals and hashCode methods of the underlying collections.

This fragment is from the book core java,then I write some code to verify it:

package collection.view;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;


public class ColsOf {
    public static void main(String[] args) {

        List<TestEqual> list1=new ArrayList<>();
        TestEqual e1 = new TestEqual(5, 3);TestEqual e2 = new TestEqual(5, 3);
        System.out.println(e1==e2);System.out.println(e1.equals(e2));
        list1.add(e1);
        List<TestEqual> imutableList = Collections.unmodifiableList(list1);
        System.out.println(imutableList.contains(e2));
        Collection<TestEqual> imutableColl = Collections.unmodifiableCollection(list1);
        System.out.println(imutableColl.contains(e2));

    }

}

class TestEqual{
    int i;
    int j;
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return i*100+j;
    }
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return this.hashCode()==obj.hashCode();
    }
    public TestEqual(int i, int j) {
        super();
        this.i = i;
        this.j = j;
    }

}

Run the code,result is:

false
true
true
true

so I can see e1==e2 is false,but imutableColl.contains(e2) is true

if imutableColl check the memory location but not the content when I invoke the contains method,then the imutableColl.contains(e2) should be false,why it is true?

If the problem is on the contains method,then how to verify the point that the book described?

Upvotes: 1

Views: 480

Answers (1)

John Bollinger
John Bollinger

Reputation: 180286

The excerpt you've presented from the docs of Collections.unmodifiableCollection() is about the equals() method of the Collection objects it returns, as in

immutableColl.equals(anotherColl)

That has nothing whatever to do with the collections' contains() method, which obeys the contract of Collection.contains(), just as it should:

returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e)).

That's exactly what you report observing. Note, too, that although the List and Set contracts specify details for how implementations' equals() methods should behave, the contract for Collections.equals() expressly disclaims any requirement to override Object.equals().

Upvotes: 4

Related Questions