10

Why does the following test fail in Java?

@Test
public void testUnmodifiableCollection() {
    Collection<String> strList = new ArrayList<String>();
    strList.add("foo1");
    strList.add("foo2");
    Collection<String> col1 = Collections.unmodifiableCollection(strList);
    Collection<String> col2 = Collections.unmodifiableCollection(strList);
    Assert.assertTrue(col1.equals(col2));
}
davis
  • 113
  • 4
  • 7
    _The returned collection does not pass the `hashCode` and `equals` operations through to the backing collection, but relies on Object's `equals` and `hashCode` methods. **This is necessary to preserve the contracts of these operations in the case that the backing collection is a set or a list**._ – Sotirios Delimanolis Jul 30 '15 at 20:38
  • 1
    Why on Earth did someone downvote this question? – Bobulous Jul 30 '15 at 21:01

1 Answers1

9

Because the call to Collections.unmodifiableCollection(Collection) returns an UnmodifiableCollection, which does not implement its own equals method and only implements the Collection interface. Therefore, Object.equals(Object) is used which compares the object references with one another. Since you are comparing two different references, the result is false.

The fact that equals (and hashCode) are not passed to the underlying collection is also documented in the Javadoc:

The returned collection does not pass the hashCode and equals operations through to the backing collection, but relies on Object's equals and hashCode methods. This is necessary to preserve the contracts of these operations in the case that the backing collection is a set or a list.

See this answer for a good explanation why anything else would violate the contracts of Lists and Sets.

Community
  • 1
  • 1
hzpz
  • 7,536
  • 1
  • 38
  • 44
  • For the above code snippet, if I use Assert.assertEquals(col1, col2); , the test passes? Why is that? Are the references same for objects col1 and col2? – davis Jul 30 '15 at 21:20
  • It's because col1.toString() is compared to col2.toString()? – davis Jul 30 '15 at 21:23
  • `Assert.assertEquals(col1, col2)` is exactly the same as `Assert.assertTrue(col1.equals(col2))` and will also fail. – hzpz Aug 01 '15 at 22:37