This example shows how to sort a HashSet in Java. This example also shows sorting a Java HashSet of custom class objects using a TreeSet and a Comparator object.
How to sort HashSet in Java?
The HashSet class in Java is a Set implementation that is backed by a HashMap instance. Just like the HashMap, the HashSet class does not make any guarantee to maintain the order of its elements. The order of the elements returned by its Iterator may not stay constant over time.
Sorting the HashSet elements does not make sense because it may not be returned in the sorted order by the HashSet iterator even after sorting it. If you want the Set functionality but still want the elements to be sorted, you can convert the HashSet to a TreeSet using the below given TreeSet constructor.
1 |
TreeSet(Collection<? extends E> collection) |
This constructor creates a new TreeSet object containing all the elements of the specified collection, sorted according to the natural order.
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; import java.util.Set; import java.util.TreeSet; public class SortJavaHashSetExample { public static void main(String[] args) { Set<Integer> hSetNumbers = new HashSet<Integer>(); hSetNumbers.add(43); hSetNumbers.add(14); hSetNumbers.add(21); hSetNumbers.add(33); System.out.println("HashSet contains: " + hSetNumbers); /* * To sort HashSet, convert it to a TreeSet * using constructor. * * The TreeSet class automatically sorts the elements. */ TreeSet<Integer> treeSetNumbers = new TreeSet<Integer>(hSetNumbers); System.out.println("Sorted HashSet: " + treeSetNumbers); } } |
Output
1 2 |
HashSet contains: [33, 21, 43, 14] Sorted HashSet: [14, 21, 33, 43] |
As we can see from the output, all the HashSet elements are automatically sorted in the TreeSet object.
How to sort HashSet of custom class objects?
In the above example, we used the HashSet of Integer type. Let’s try with a custom class object this time.
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; import java.util.Set; import java.util.TreeSet; class Subject{ private int subjectId; public Subject(int subjectId){ this.subjectId = subjectId; } public String toString(){ return "Subject: " + this.subjectId; } } public class SortJavaHashSetExample { public static void main(String[] args) { Set<Subject> hSetSubjects = new HashSet<Subject>(); hSetSubjects.add( new Subject(3) ); hSetSubjects.add( new Subject(4) ); hSetSubjects.add( new Subject(3) ); hSetSubjects.add( new Subject(5) ); hSetSubjects.add( new Subject(1) ); System.out.println("HashSet contains: " + hSetSubjects); //convert to TreeSet to sort TreeSet<Subject> treeSetSubjects = new TreeSet<Subject>(hSetSubjects); } } |
Output
1 2 3 4 5 6 7 8 |
HashSet contains: [Subject: 3, Subject: 1, Subject: 3, Subject: 4, Subject: 5] Exception in thread "main" java.lang.ClassCastException: com.javacodeexamples.collections.hashset.Subject cannot be cast to java.lang.Comparable at java.util.TreeMap.compare(Unknown Source) at java.util.TreeMap.put(Unknown Source) at java.util.TreeSet.add(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at java.util.TreeSet.addAll(Unknown Source) at java.util.TreeSet.<init>(Unknown Source) |
The elements inserted into TreeSet either must implement the Comparable interface or a custom Comparator must be provided at the TreeSet creation time using the constructor. We did neither of that in our Subject custom class and hence the java.lang.ClassCastException was thrown.
In order to solve this exception, we can either implement the Comparable interface in the Subject class or we can provide a custom Comparator in the TreeSet constructor. I am going to show how to sort HashSet using the Comparator below.
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import java.util.Comparator; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; class Subject{ private int subjectId; public Subject(int subjectId){ this.subjectId = subjectId; } public String toString(){ return "Subject: " + this.subjectId; } public int getSubjectId(){ return this.subjectId; } } /* * A custom comparator for the Subject class to * sort the objects in an ascending order. */ class SubjectComparator implements Comparator<Subject>{ /* * This method will sort the Subject objects in the * ascending order */ public int compare(Subject s1, Subject s2) { return s1.getSubjectId() - s2.getSubjectId(); } } /* * A custom comparator for the Subject class to * sort the objects in a descending order. */ class SubjectComparatorDescending implements Comparator<Subject>{ /* * This method will sort the Subject objects in the * descending order */ public int compare(Subject s1, Subject s2) { return s2.getSubjectId() - s1.getSubjectId(); } } public class SortJavaHashSetExample { public static void main(String[] args) { Set<Subject> hSetSubjects = new HashSet<Subject>(); hSetSubjects.add( new Subject(2) ); hSetSubjects.add( new Subject(4) ); hSetSubjects.add( new Subject(3) ); hSetSubjects.add( new Subject(5) ); hSetSubjects.add( new Subject(1) ); System.out.println("HashSet contains: "); System.out.println(hSetSubjects); /* * Create new TreeSet with ascending order comparator */ TreeSet<Subject> treeSetSubjectsAsc = new TreeSet<Subject>(new SubjectComparator()); //add all elements of HashSet to TreeSet treeSetSubjectsAsc.addAll(hSetSubjects); System.out.println("Sorted HashSet in ascending order: "); System.out.println(treeSetSubjectsAsc); //similarly, sort HashSet in descending order TreeSet<Subject> treeSetSubjectsDesc = new TreeSet<Subject>(new SubjectComparatorDescending()); treeSetSubjectsDesc.addAll(hSetSubjects); System.out.println("Sorted HashSet in descending order: "); System.out.println(treeSetSubjectsDesc); } } |
Output
1 2 3 4 5 6 |
HashSet contains: [Subject: 3, Subject: 1, Subject: 2, Subject: 4, Subject: 5] Sorted HashSet in ascending order: [Subject: 1, Subject: 2, Subject: 3, Subject: 4, Subject: 5] Sorted HashSet in descending order: [Subject: 5, Subject: 4, Subject: 3, Subject: 2, Subject: 1] |
As we can see from the output, the HashSet of custom class objects is now sorted according to the order defined by the Comparator object.
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
Excellent JBO, Rahim