• Post Reply Bookmark Topic Watch Topic
  • New Topic

ArrayList.contains confusion  RSS feed

 
Joey Dale
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have created a class "Word" which overrides hashcode and equals. When I add a Word to a ArrayList and then call ArrayList.contains() with an object that returns true for equals, ArrayList.contains() returns false.

What is causing the absence of the expected behavior? Here is the source for Word, and a Simple Test Class:

Word:


Test Class:


I am expecting 4 trues and 3 identical hashcodes. Here is the output:

true
true
false
true
3556498
3556498
3556498

Thanks
-Joey
 
Paul Clapham
Sheriff
Posts: 22819
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your equals() method isn't symmetric, as a proper equals() method should be. In particular



and



don't return the same value. So when you ask whether your List<Word> contains a String object, you're assuming that the former is going to be called but perhaps it's the latter.
 
Alex Theedom
Author
Ranch Hand
Posts: 77
5
Java Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To understand what is really happening its essential to take a look at the source code for the contains() method of the ArrayList class and the equals() method of the String class. By doing so you will see that you are passing in a String object to the contains() method of ArrayList which then calls another method (indexOf()) passing it your String object. This method then calls the equals method of your String object passing it each element in your ArrayList in turn. The String's equals method first tests to see if the two objects have the same reference value (which they don't as they are different objects) then it tests to see if the object passed in (a Word object) is an instance of String, which it is not and then it returns false, it repeats this for each element in your ArrayList, and as none of the elements in your ArrayList are an instance of String it returns -1, then contains returns false.

I think that you were assuming that it would call the equals method of the Word object. A reasonable assumption but wrong, which is why it is essential to check out the source code to ensure that you know what is really happening under the surface.

Essentially the response from the previous post is correct StringObject.equals(WordObject) is not symmetrical with WordObject.equals(StringObject), their equal methods have different implementations.

As for a solution to this problem, I think that I have given you a big enough hint so that you can figure it out for yourself: think symmetrical!
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!