I was given the task to make two different objects of the class User with the same fields and 4 options for adding them to the HashSet :
- Do not override either
equals()orhashCode()of theUserclass. - Override
equals(). - Override only
hashCode(). - Override both
equals()andhashCode().
In all cases, you need to say what will be the size and why.
The User class looks like this:
public class User { public String name; public int children; public Calendar birthday; public User(String name, int children, Calendar birthday) { this.name = name; this.children = children; this.birthday = birthday; } } I override hashCode() like this:
@Override public int hashCode() { int hash = 31; hash = hash * 17 + name.hashCode(); hash = hash * 17 + birthday.hashCode(); hash = hash * 17 + children; return hash; } equals() I redefine as:
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; UserEquals ue = (UserEquals) obj; return this.hashCode() == ue.hashCode() || (this.birthday.getTimeInMillis() == ue.getBirthday().getTimeInMillis() && this.children == ue.getChildren() && this.name.equals(ue.getName())); } If my options for overriding methods are incorrect, please correct me.
The test generally looks like this:
@Test public void whenThen() { Calendar calendar = new GregorianCalendar(1988, Calendar.JUNE, 19); User user1 = new User("Pavel", 0, calendar); User user2 = new User("Pavel", 0, calendar); Set<User> set = new HashSet<>(); set.add(user1); set.add(user2); int result = set.size(); assertThat(result, is(2)); } And here is the question:
When I do not override anything in the User class, then I have size == 2 , and when I override only equals() is also size == 2 . And I thought that HashSet does not use the equals() method at all, but immediately uses hashCode() (that is, a comparison of the contents of the fields in equals() does not affect the situation).
But when I redefined only hashCode() separately, the situation also did not change: size still remained equal to 2 . And only when I redefined both methods (and hashCode() , and equals() ), size became equal to 1 .
No matter how much I wander through the HashSet source, I can’t fully understand how it still works.
What is the idea of the HashSet class in identifying what to consider as a duplicate and what is not?
HashSetsources, you will see that the data in it is stored in theHashMap, therefore,HashSetworks exactly the same asHashMapwith the correction thatObjectused as a value for all objects. I’ll write the answer now, but I’ll have to wait a bit, since this topic cannot be explained in two words. - post_zeew