Sort a HashMap in Java

1. Introduction

In this quick tutorial, we’ll learn how to sort a HashMap in Java.

More specifically, we’ll look at sorting HashMap entries by their key or value using:

  • TreeMap
  • ArrayList and Collections.sort()
  • TreeSet
  • Using the Stream API, and finally,
  • Using the Guava library

2. Using a TreeMap

As we know, keys in TreeMap are sorted using their natural order. This is a good solution when we want to sort the key-value pairs by their key. So the idea is to push all the data from our HashMap into the TreeMap.

For starters, let’s define a HashMap and initialize it with some data:

Map<String, Employee> map = new HashMap<>();

Employee employee1 = new Employee(1L, "Mher");
map.put(employee1.getName(), employee1);
Employee employee2 = new Employee(22L, "Annie");
map.put(employee2.getName(), employee2);
Employee employee3 = new Employee(8L, "John");
map.put(employee3.getName(), employee3);
Employee employee4 = new Employee(2L, "George");
map.put(employee4.getName(), employee4);

For the Employee class, note that we’ve implemented Comparable:

public class Employee implements Comparable<Employee> {

    private Long id;
    private String name;

    // constructor, getters, setters

    // override equals and hashCode
    @Override
    public int compareTo(Employee employee) {
        return (int)(this.id - employee.getId());
    }
}

Next, we store the entries in the TreeMap by using its constructor:

TreeMap<String, Employee> sorted = new TreeMap<>(map);

Or, the putAll method to copy the data:

TreeMap<String, Employee> sorted = new TreeMap<>();
sorted.putAll(map);

And that’s it! To make sure our map entries are sorted by key, let’s print them out:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

As we see, the keys are sorted in natural order.

3. Using ArrayList

Of course, we can sort the entries of the map with the help of ArrayList. The key difference from the previous method is that we don’t maintain the Map interface here.

3.1. Sort by Key

Let’s load the key set into an ArrayList:

List<String> employeeByKey = new ArrayList<>(map.keySet());
Collections.sort(employeeByKey);

And the output is:

[Annie, George, John, Mher]

3.2. Sort by Value

Now, what if we want to sort our map values by the id field of Employee object? We can use an ArrayList for that, too.

First, let’s copy the values into the list:

List<Employee> employeeById = new ArrayList<>(map.values());

And after that, we sort it:

Collections.sort(employeeById);

Remember that this works because Employee implements the Comparable interface. Otherwise, we’d need to define a manual comparator for our call to Collections.sort.

To check the results, we print the employeeById:

[Employee{id=1, name='Mher'}, 
Employee{id=2, name='George'}, 
Employee{id=8, name='John'}, 
Employee{id=22, name='Annie'}]

As we see, the objects are sorted by their id field.

4. Using a TreeSet 

In case we don’t want to accept duplicate values in our sorted collection, there is a nice solution with TreeSet.

First, let’s add some duplicate entries to our initial map:

Employee employee5 = new Employee(1L, "Mher");
map.put(employee5.getName(), employee5);
Employee employee6 = new Employee(22L, "Annie");
map.put(employee6.getName(), employee6);

4.1. Sort by Key

To sort the map by its key entries:

SortedSet<String> keySet = new TreeSet<>(map.keySet());

Let’s print the keySet and see the output:

[Annie, George, John, Mher]

Now we have the map keys sorted without the duplicates.

4.2. Sort by Value

Likewise, for the map values, the conversion code looks like:

SortedSet<Employee> values = new TreeSet<>(map.values());

And the results are:

[Employee{id=1, name='Mher'}, 
Employee{id=2, name='George'}, 
Employee{id=8, name='John'}, 
Employee{id=22, name='Annie'}]

As we can see, there are no duplicates in the output. This works with custom objects when we override equals and hashCode.

5. Using Lambdas and Streams

Since the Java 8, we can use the Stream API and lambda expressions to sort the map. All we need is to call the sorted method over the map’s stream pipeline.

5.1. Sort by Key

To sort by key, we use the comparingByKey comparator:

map.entrySet()
  .stream()
  .sorted(Map.Entry.<String, Employee>comparingByKey())
  .forEach(System.out::println);

The final forEach stage prints out the results:

Annie=Employee{id=22, name='Annie'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Mher=Employee{id=1, name='Mher'}

By default, the sorting mode is ascending.

5.2. Sort by Value

Of course, we can sort by the Employee objects as well:

map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .forEach(System.out::println);

As we see, the code above prints out a map sorted by the id fields of Employee objects:

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

Additionally, we can collect the results into a new map:

Map<String, Employee> result = map.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .collect(Collectors.toMap(
    Map.Entry::getKey, 
    Map.Entry::getValue, 
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

Note that we collected our results into a LinkedHashMap. By default, Collectors.toMap returns a new HashMap, but as we know, HashMap doesn’t guarantee iteration order, while LinkedHashMap does.

6. Using Guava

Lastly, a library that allows us to sort the HashMap is Guava. Before we start, it’ll be useful to check our write-up about maps in Guava.

First, let’s declare an Ordering as we want to sort our map by Employee’s Id field:

Ordering naturalOrdering = Ordering.natural()
  .onResultOf(Functions.forMap(map, null));

Now, all we need is to use ImmutableSortedMap to illustrate the results:

ImmutableSortedMap.copyOf(map, naturalOrdering);

And once again, the output is a map ordered by the id field:

Mher=Employee{id=1, name='Mher'}
George=Employee{id=2, name='George'}
John=Employee{id=8, name='John'}
Annie=Employee{id=22, name='Annie'}

7. Summary

In this article, we reviewed a number of ways to sort a HashMap by key or by value.

And we took a close look at how we can do this when the attribute is a custom class by implementing Comparable.

Finally, as always, the code used during the discussion can be found over on GitHub.

Related posts:

How to Remove the Last Character of a String?
Spring Security Form Login
Java Byte Array to InputStream
Java Program to Describe the Representation of Graph using Incidence List
Using a List of Values in a JdbcTemplate IN Clause
Java Program to Represent Graph Using Incidence Matrix
Connect through a Proxy
Derived Query Methods in Spring Data JPA Repositories
Java Program to Implement Control Table
Java Perform to a 2D FFT Inplace Given a Complex 2D Array
Java Program to Compute Determinant of a Matrix
The Basics of Java Security
Configuring a DataSource Programmatically in Spring Boot
Spring Security Registration – Resend Verification Email
Java Program to Find Nearest Neighbor for Dynamic Data Set
Hướng dẫn sử dụng Lớp FilePermission trong java
Spring MVC Content Negotiation
Java Program to Implement Radix Sort
Hướng dẫn Java Design Pattern – Intercepting Filter
Một số nguyên tắc, định luật trong lập trình
Java Program to Implement Graham Scan Algorithm to Find the Convex Hull
Registration with Spring Security – Password Encoding
Using Java Assertions
Java Switch Statement
Tạo ứng dụng Java RESTful Client với thư viện Retrofit
Java Program to Implement Gauss Seidel Method
Hướng dẫn Java Design Pattern – Abstract Factory
HashMap trong Java hoạt động như thế nào?
Java CyclicBarrier vs CountDownLatch
Hướng dẫn sử dụng Java Generics
Phương thức tham chiếu trong Java 8 – Method References
Thực thi nhiều tác vụ cùng lúc như thế nào trong Java?