[java] How to sort a HashSet?

For lists, we use the Collections.sort(List) method. What if we want to sort a HashSet?

This question is related to java sorting collections set hashset

The answer is


We can not decide that the elements of a HashSet would be sorted automatically. But we can sort them by converting into TreeSet or any List like ArrayList or LinkedList etc.

// Create a TreeSet object of class E
TreeSet<E> ts = new TreeSet<E> ();

// Convert your HashSet into TreeSet
ts.addAll(yourHashSet);

System.out.println(ts.toString() + "\t Sorted Automatically");


If you want want the end Collection to be in the form of Set and if you want to define your own natural order rather than that of TreeSet then -

1. Convert the HashSet into List
2. Custom sort the List using Comparator
3. Convert back the List into LinkedHashSet to maintain order
4. Display the LinkedHashSet

Sample program -

package demo31;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class App26 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        addElements(set);
        List<String> list = new LinkedList<>();
        list = convertToList(set);
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int flag = s2.length() - s1.length();
                if(flag != 0) {
                    return flag;
                } else {
                    return -s1.compareTo(s2);
                }
            }
        });
        Set<String> set2 = new LinkedHashSet<>();
        set2 = convertToSet(list);
        displayElements(set2);
    }
    public static void addElements(Set<String> set) {
        set.add("Hippopotamus");
        set.add("Rhinocerous");
        set.add("Zebra");
        set.add("Tiger");
        set.add("Giraffe");
        set.add("Cheetah");
        set.add("Wolf");
        set.add("Fox");
        set.add("Dog");
        set.add("Cat");
    }
    public static List<String> convertToList(Set<String> set) {
        List<String> list = new LinkedList<>();
        for(String element: set) {
            list.add(element);
        }
        return list;
    }
    public static Set<String> convertToSet(List<String> list) {
        Set<String> set = new LinkedHashSet<>();
        for(String element: list) {
            set.add(element);
        }
        return set;
    }
    public static void displayElements(Set<String> set) {
        System.out.println(set);
    }
}

Output -

[Hippopotamus, Rhinocerous, Giraffe, Cheetah, Zebra, Tiger, Wolf, Fox, Dog, Cat]

Here the collection has been sorted as -

First - Descending order of String length
Second - Descending order of String alphabetical hierarchy


Elements in HashSet can't be sorted. Whenever you put elements into HashSet, it can mess up the ordering of the whole set. It is deliberately designed like that for performance. When you don't care about the order, HashSet will be the most efficient set for fast insertion and search.

TreeSet will sort all the elements automatically every time you insert an element.

Perhaps, what you are trying to do is to sort just once. In that case, TreeSet is not the best option because it needs to determine the placing of newly added elements all the time.

The most efficient solution is to use ArrayList. Create a new list and add all the elements then sort it once. If you want to retain only unique elements (remove all duplicates like set does, then put the list into a LinkedHashSet, it will retain the order you have already sorted)

List<Integer> list = new ArrayList<>();
list.add(6);
list.add(4);
list.add(4);
list.add(5);
Collections.sort(list);
Set<Integer> unique = new LinkedHashSet<>(list); // 4 5 6
// The above line is not copying the objects! It only copies references.

Now, you've gotten a sorted set if you want it in a list form then convert it into list.


You can wrap it in a TreeSet like this:

Set mySet = new HashSet();
mySet.add(4);
mySet.add(5);
mySet.add(3);
mySet.add(1);
System.out.println("mySet items "+ mySet);   

TreeSet treeSet = new TreeSet(mySet);   
System.out.println("treeSet items "+ treeSet);   

output :
mySet items [1, 3, 4, 5]
treeSet items [1, 3, 4, 5]

Set mySet = new HashSet();
mySet.add("five");
mySet.add("elf");
mySet.add("four");
mySet.add("six");
mySet.add("two");
System.out.println("mySet items "+ mySet);

TreeSet treeSet = new TreeSet(mySet);
System.out.println("treeSet items "+ treeSet);

output:
mySet items [six, four, five, two, elf]
treeSet items [elf, five, four, six, two]

requirement for this method is that the objects of the set/list should be comparable (implement the Comparable interface)


You can use guava library for the same

Set<String> sortedSet = FluentIterable.from(myHashSet).toSortedSet(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        // descending order of relevance
        //required code
    }
});

A HashSet does not guarantee any order of its elements. If you need this guarantee, consider using a TreeSet to hold your elements.

However if you just need your elements sorted for this one occurrence, then just temporarily create a List and sort that:

Set<?> yourHashSet = new HashSet<>();

...

List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);

you can do this in the following ways:

Method 1:

  1. Create a list and store all the hashset values into it
  2. sort the list using Collections.sort()
  3. Store the list back into LinkedHashSet as it preserves the insertion order

Method 2:

  • Create a treeSet and store all the values into it.

Method 2 is more preferable because the other method consumes lot of time to transfer data back and forth between hashset and list.


1. Add all set element in list -> al.addAll(s);
2. Sort all the elements in list using -> Collections.sort(al);


 public class SortSetProblem {
 public static void main(String[] args) {
    ArrayList<String> al = new ArrayList();
    Set<String> s = new HashSet<>();
    s.add("ved");
    s.add("prakash");
    s.add("sharma");
    s.add("apple");
    s.add("ved");
    s.add("banana");
    System.out.println("Before Sorting");
    for (String s1 : s) {
        System.out.print("  " + s1);
    }

    System.out.println("After Sorting");
    al.addAll(s);
    Collections.sort(al);
    for (String set : al) {
        System.out.print(" " + set);
    }
  }
 }

input - ved prakash sharma apple ved banana

Output - apple banana prakash sharma ved


You can use Java 8 collectors and TreeSet

list.stream().collect(Collectors.toCollection(TreeSet::new))


Add all your objects to the TreeSet, you will get a sorted Set. Below is a raw example.

HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);

TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]

This simple command did the trick for me:

myHashSet.toList.sorted

I used this within a print statement, so if you need to actually persist the ordering, you may need to use TreeSets or other structures proposed on this thread.


You can use TreeSet as mentioned in other answers.

Here's a little more elaboration on how to use it:

TreeSet<String> ts = new TreeSet<String>();
ts.add("b1");
ts.add("b3");
ts.add("b2");
ts.add("a1");
ts.add("a2");
System.out.println(ts);
for (String s: ts)
    System.out.println(s);

Output:

[a1, a2, a3, a4, a5]
a1
a2
b1
b2
b3

Based on the answer given by @LazerBanana i will put my own example of a Set sorted by the Id of the Object:

Set<Clazz> yourSet = [...];

yourSet.stream().sorted(new Comparator<Clazz>() {
    @Override
    public int compare(Clazz o1, Clazz o2) {
        return o1.getId().compareTo(o2.getId());
    }
}).collect(Collectors.toList()); // Returns the sorted List (using toSet() wont work)

Java 8 way to sort it would be:

fooHashSet.stream()
  .sorted(Comparator.comparing(Foo::getSize)) //comparator - how you want to sort it
  .collect(Collectors.toList()); //collector - what you want to collect it to

*Foo::getSize it's an example how to sort the HashSet of YourItem's naturally by size.

*Collectors.toList() is going to collect the result of sorting into a List the you will need to capture it with List<Foo> sortedListOfFoo =


You can use a TreeSet instead.


In my humble opinion , LazerBanana's answer should be the top rated answer & accepted because all the other answers pointing to java.util.TreeSet ( or first convert to list then call Collections.sort(...) on the converted list ) didn't bothered to ask OP as what kind of objects your HashSet has i.e. if those elements have a predefined natural ordering or not & that is not optional question but a mandatory question.

You just can't go in & start putting your HashSet elements into a TreeSet if element type doesn't already implement Comparable interface or if you are not explicitly passing Comparator to TreeSet constructor.

From TreeSet JavaDoc ,

Constructs a new, empty tree set, sorted according to the natural ordering of its elements. All elements inserted into the set must implement the Comparable interface. Furthermore, all such elements must be mutually comparable: e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the set. If the user attempts to add an element to the set that violates this constraint (for example, the user attempts to add a string element to a set whose elements are integers), the add call will throw a ClassCastException.

That is why only all Java8 stream based answers - where you define your comparator on the spot - only make sense because implementing comparable in POJO becomes optional. Programmer defines comparator as and when needed. Trying to collect into TreeSet without asking this fundamental question is also incorrect ( Ninja's answer). Assuming object types to be String or Integer is also incorrect.

Having said that, other concerns like ,

  1. Sorting Performance
  2. Memory Foot Print ( retaining original set and creating new sorted sets each time sorting is done or wish to sort the set in - place etc etc )

should be the other relevant points too. Just pointing to API shouldn't be only intention.

Since Original set already contains only unique elements & that constraint is also maintained by sorted set so original set needs to be cleared from memory since data is duplicated.


Use java.util.TreeSet as the actual object. When you iterate over this collection, the values come back in a well-defined order.

If you use java.util.HashSet then the order depends on an internal hash function which is almost certainly not lexicographic (based on content).


Just in-case you don't wanna use a TreeSet you could try this.

set = set.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to sorting

Sort Array of object by object field in Angular 6 Sorting a list with stream.sorted() in Java How to sort dates from Oldest to Newest in Excel? how to sort pandas dataframe from one column Reverse a comparator in Java 8 Find the unique values in a column and then sort them pandas groupby sort within groups pandas groupby sort descending order Efficiently sorting a numpy array in descending order? Swift: Sort array of objects alphabetically

Examples related to collections

Kotlin's List missing "add", "remove", Map missing "put", etc? How to unset (remove) a collection element after fetching it? How can I get a List from some class properties with Java 8 Stream? Java 8 stream map to list of keys sorted by values How to convert String into Hashmap in java How can I turn a List of Lists into a List in Java 8? MongoDB Show all contents from all collections Get nth character of a string in Swift programming language Java 8 Distinct by property Is there a typescript List<> and/or Map<> class/library?

Examples related to set

java, get set methods golang why don't we have a set datastructure Simplest way to merge ES6 Maps/Sets? Swift Set to Array JavaScript Array to Set How to sort a HashSet? Python Set Comprehension How to get first item from a java.util.Set? Getting the difference between two sets Python convert set to string and vice versa

Examples related to hashset

How to sort a HashSet? Does adding a duplicate value to a HashSet/HashMap replace the previous value How to Iterate over a Set/HashSet without an Iterator? How to calculate the intersection of two sets? Why there is no ConcurrentHashSet against ConcurrentHashMap Hashcode and Equals for Hashset Collection that allows only unique items in .NET? HashSet vs LinkedHashSet Define: What is a HashSet? Difference between HashSet and HashMap?