Newbie question about java HashSet
Set<User> s = new HashSet<User>();
User u = new User();
u.setName("name1");
s.add(u);
u.setName("name3");
System.out.println(s.contains(u));
Can someone explain why this code output false ? Moreover this code does not even call equals method of User. But according to the sources of HashSet and HashMap it have to call it. Method equals of User simply calls equals on user's name. Method hashCode return hashCode of user's name
If the hash code method is based on the
name
field, and you then change it after adding the object, then the secondcontains
check will use the new hash value, and won't find the object you were looking for. This is becauseHashSet
s first search by hash code, so they won't bother callingequals
if that search fails.The only way this would work is if you hadn't overridden
equals
(and so the default reference equality was used) and you got lucky and the hash codes of the two objects were equal. But this is a really unlikely scenario, and you shouldn't rely on it.In general, you should never update an object after you have added it to a
HashSet
if that change will also change its hashcode.Since your new
User
has a different hashcode, the HashSet knows that it isn't equal.HashSets store their items according to their hashcodes.
The HashSet will only call
equals
if it finds an item with the same hashcode, to make sure that the two items are actually equal (as opposed to a hash collision)