Concept

Why are equals() and hashCode() important when searching and using sets?

ComputerScienceOne / Importance of javaequals() and javahashCode() Methods

"Recall that in Chapter 34 we briefly discussed the importance of overloading the equals() and hashCode() methods of our objects. We reiterate this in the context of searching. Recall that the Set and List collections provide linear search methods that do not require the use of a Comparator. This is because the collections use the object’s equals() to determine when a particular instance has been found. In the case of hash-based data structures such as HashSet, the hashCode() method is also important.\n\nTo illustrate the importance of these methods, consider the following code.\n\n1 Student a = new Student(\"Joe\", \"Smith\", 1234, 3.5);\n\n2 Student b = new Student(\"Joe\", \"Smith\", 1234, 3.5);\n\n3\n\n4 Set<Student> s = new HashSet<Student>();\n\n5 s.add(a);\n\n6 s.add(b);\n\nIf we do not override the equals() and hashCode() methods, at the end of this code snippet, the set will contain both of the Student instances even though they are conceptually the same object (all of their member variables will have the same values). However, if we do override the equals() and hashCode() methods as described in Section 34.5, then the code snippet above would result in the Set only having one object (the first one added). This is because during the attempt to add the second instance, the equals() method would have returned true when compared to the first instance and the duplicate element would not have been added to the Set (as Sets do not allow duplicates).\n\nAlso recall that we saw some of the advantages of immutable objects. Again, we point out another advantage. Suppose that we properly override the equals() and the hashCode() methods in our Student object. Further, suppose that we make our Student class mutable: allowing a user to change the ID via a setter. Consider the following code snippet.\n\n1 Student a = new Student(\"Joe\", \"Smith\", 1234, 3.5);\n\n2 Student b = new Student(\"Joe\", \"Smith\", 5679, 3.5);\n\n3\n\n4 Set<Student> s = new HashSet<Student>();\n\n5 s.add(a);\n\n6 s.add(b);\n\n7 //s now contains both students\n\n8 b.setId(1234);\n\nWhen we instantiate the two Student instances, they are distinct as their IDs are different. So when we add them to the set, their equals() method returns false and they are both added to the Set. However, when we change the ID using the setter on the last line, both objects are now identical, violating the no-duplicates property of the Set. This is not a failing of the Set class, just one of the many consequences of designing mutable objects."

Related Ideas

Why are equals() and hashCode() important when searching and using sets? | ComputerScienceOne | Bifalgorithm | Bifalgorithm