This example shows how to compare two HashSet objects to check if they are equal in Java. This example also shows how to compare HashSet objects using the equals method.
How to compare two HashSet objects for equality in Java?
The HashSet class inherits the equals
method from the parent class AbstractSet class.
1 |
public boolean equals(Object o) |
This method compares the specified object with this Set object and returns true if the specified object is a Set, both have the same number of elements (HashSet size), and every element of this Set is also contained in the specified Set object.
Let’s have a look at the source code of the equals
method taken from the OpenJDK 8 AbstractSet class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Set)) return false; Collection<?> c = (Collection<?>) o; if (c.size() != size()) return false; try { return containsAll(c); } catch (ClassCastException unused) { return false; } catch (NullPointerException unused) { return false; } } |
As we can see from the code, there are some performance shorts cuts applied before comparing the elements of two Set objects. First of all, it checks if the two references point to the same object, if yes, it returns true. Then, if the specified object is not an instance of a Set, it returns false. Once that check is done, it compares the size of two Set objects. If the size is not the same, the Set objects are not equal.
If sizes are equal for both the Set objects, it checks if all the elements of this Set are also contained in the specified Set object. If yes, it returns true, false otherwise.
In short, the equals
method compares two Set objects by elements i.e. the actual content of the Set, not just the references. The below example shows how to use the equals
method to compare two HashSet objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.util.HashSet; public class JavaHashSetCompareExample { public static void main(String[] args) { //first HashSet HashSet<Integer> hSet1 = new HashSet<Integer>(); hSet1.add(1); hSet1.add(2); hSet1.add(3); //second HashSet HashSet<Integer> hSet2 = new HashSet<Integer>(); hSet2.add(3); hSet2.add(2); hSet2.add(1); System.out.println( "Equal? " + hSet1.equals(hSet2) ); //remove an element from 1 HashSet hSet1.remove(2); System.out.println( "Equal? " + hSet1.equals(hSet2) ); } } |
Output
1 2 |
Equal? true Equal? false |
How to compare two HashSet objects of custom class elements?
Let’s see what happens when we compare the set objects having custom class elements using the equals
method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import java.util.HashSet; class Document{ private int documentId; public Document(int documentId){ this.documentId = documentId; } public String toString(){ return "Document: " + documentId; } } public class JavaHashSetCompareExample { public static void main(String[] args) { HashSet<Document> hSetDocuments1 = new HashSet<Document>(); hSetDocuments1.add(new Document(1)); hSetDocuments1.add(new Document(2)); hSetDocuments1.add(new Document(3)); HashSet<Document> hSetDocuments2 = new HashSet<Document>(); hSetDocuments2.add(new Document(1)); hSetDocuments2.add(new Document(2)); hSetDocuments2.add(new Document(3)); System.out.println("Equals? " + hSetDocuments1.equals(hSetDocuments2)); } } |
Output
1 |
Equals? false |
As we can see from the output, even if the two HashSet objects were having the same custom class objects, the equals
method returned false.
As we have seen in the source code of the HashSet equals
method given at the top, the equals
method checks if all the elements of this Set object are also contained in the specified Set object using the containsAll
method. The containsAll
method relies on the equals
method of the elements to compare the objects.
Since we have not implemented the equals
method in our Document custom class, the equals
method inherited from the Object class is used which only compares the object references, not the actual content. That is the reason the containsAll
returns false and in turn the HashSet equals
method returns false.
Let’s implement the equals
and hashCode
methods in the Document class and try again.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import java.util.HashSet; class Document{ private int documentId; public Document(int documentId){ this.documentId = documentId; } public String toString(){ return "Document: " + documentId; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + documentId; return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Document other = (Document) obj; if (documentId != other.documentId) return false; return true; } } public class JavaHashSetCompareExample { public static void main(String[] args) { HashSet<Document> hSetDocuments1 = new HashSet<Document>(); hSetDocuments1.add(new Document(1)); hSetDocuments1.add(new Document(2)); hSetDocuments1.add(new Document(3)); HashSet<Document> hSetDocuments2 = new HashSet<Document>(); hSetDocuments2.add(new Document(1)); hSetDocuments2.add(new Document(2)); hSetDocuments2.add(new Document(3)); System.out.println("Equals? " + hSetDocuments1.equals(hSetDocuments2)); } } |
Output
1 |
Equals? true |
It worked this time. Always remember to override the equals
and hashCode
methods in your custom class for the HashSet or any other Set comparisons to work properly.
This example is a part of the HashSet in Java Tutorial with Examples.
Please let me know your views in the comments section below.
References:
Java 8 HashSet