I initially started this as a test for the best practice theory of the question I wanted to ask here, but in this process I found interesting behavior in the java.Set class. Initially, I wanted to know any potential errors of this approach, but now that I see that this does not work at all, I would like to know why.
I have some objects that are containers for database objects for my application. All objects have unique integer id , and hashCode() and equals() determined by integer identifiers (for storage in hash networks).
Well, I need the ability to check if the hashset contains the object specified only for the identifier. Of course, I could create a new instance of the object and test it. But, just for the kicks, I wanted to see if I could do it. Of course, this is also trivial with a hashmap, so this is really not an important issue, just for fun and knowledge.
So, I created a class and tried to call contains() on an integer instead of an object instance. Netbeans, of course, gives a funny warning for this.
Suspicious call to java.util.Collection.contains: Given object cannot contain instances of int (expected Person)
Ignoring the error and running the code, I was shocked to find that Java does not even call the equals method. I put the debugging System.out.println() in my equals method to check and yep, it is not even being called.
In the code below, the expected result should be (if my theory were correct ):
Here Yes Here Yes
or (if my theory was wrong ):
Here Yes Here No
However, the output is:
Here Yes No
Note that there is no "Here" before "No", proving that the equals method is not even called.
Can anyone shed some light? I was always told to add this to equals() for efficiency:
if (!(obj instanceof Person)) return false;
But if equals() is not even called in such a situation, then this would be pointless.
Here is the SSCCE:
Thank you for your time.
import java.util.LinkedHashSet; import java.util.Set; public class Test7 { public static void main(String[] args) { class Person { public final int id; public final String name; public Person(int id, String name) { this.id = id; this.name = name; } @Override public boolean equals(Object obj) { System.out.println("Here"); if (this == obj) return true; if (obj instanceof Person) return id == ((Person)obj).id; else if(obj instanceof Integer) return id == (Integer)obj; else { System.out.println("Returning False"); return false; } } @Override public int hashCode() { return id; } } Set<Person> set = new LinkedHashSet<Person>(); set.add(new Person(1, "Bob")); set.add(new Person(2, "George")); set.add(new Person(3, "Sam")); if(set.contains(new Person(1, "Bob"))) System.out.println("Yes"); else System.out.println("No"); if(set.contains(1)) System.out.println("Yes"); else System.out.println("No"); } }