How to Sort a HashMap by Value in Java

In this tutorial, we'll take a look at how to sort a HashMap by value in Java.

Let's go ahead and create a simple HashMap:

Map<String, Integer> unsortedMap = new HashMap();

unsortedMap.put("John", 21);
unsortedMap.put("Maria", 34);
unsortedMap.put("Mark", 31);
unsortedMap.put("Sydney", 24);

unsortedMap.entrySet().forEach(System.out::println);

We've got Strings as keys, and Integers as values. And we'd like to sort this map based on the values.

HashMaps don't guarantee to maintain the order of its elements in any case. The order can change through time, and they most definitely won't be printed back in the order of insertion:

John=21
Mark=31
Maria=34
Sydney=24

If you re-run this program, it'll keep this order, since HashMaps order their elements into bins, based on the hash value of the keys. When printing values from a HashMap, its contents are printed sequentially, so the results will stay the same if we re-run the program multiple times.

Note: TreeMap extends the SortedMap interface, unlike the HashMap implementation. TreeMaps are meant to be the sorted counterpart, however, TreeMaps only sort by keys, given a comparator.

Sort HashMap by Value with LinkedHashMap

LinkedHashMap preserves the order of insertion. It keeps a doubly-linked list of all entries, allowing you to very naturally access and iterate over its elements.

So, the easiest way to convert an unsorted HashMap into a LinkedHashMap is to add the elements in the order we'd like them to be in.

Sort HashMap in Ascending Order

To sort the unsortedMap we've seen earlier, we'll create a new LinkedHashMap to house the elements in the order we want them to be in.

Let's start off with sorting a HashMap in ascending order:

Map<String, Integer> sortedMap = unsortedMap.entrySet().stream()
        .sorted(Comparator.comparingInt(e -> e.getValue()))
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (a, b) -> { throw new AssertionError(); },
                LinkedHashMap::new
        ));

sortedMap.entrySet().forEach(System.out::println);

What we've done here is streamed the unsortedMap's set of Map.Entry objects. Then, using the sorted() method, we can use various Comparators to specify how the entries are compared.

Since we're dealing with simple integers, we can easily use Comparator.comparingInt() method, and pass in a Lambda Expression. Through this expression, we supply the sort key from type T (in our case, Integer). This method then returns a Comparator that compares that sort key.

Once they're sorted, we can collect() them into a new map, via the Collectors.toMap() call, where we use the same Map.Entry::getKey and Map.Entry::getValue as in the unsortedMap.

Finally, a new LinkedHashMap is instantiated, into which all of these elements, in sorted order, are inserted.

Running this code results in:

John=21
Sydney=24
Mark=31
Maria=34

Alternatively, instead of Comparator.comparingInt(), you can use Map.Entry.comparingByValue():

Map<String, Integer> sortedMap = unsortedMap.entrySet().stream()
        .sorted(Map.Entry.comparingByValue())
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (a, b) -> { throw new AssertionError(); },
                LinkedHashMap::new
        ));

sortedMap.entrySet().forEach(System.out::println);

However, with this approach, you can't specify your own logic for the comparisons. Comparable values, like Integers, are sorted with the under-the-hood implementation. You could specify a custom object and specify your own comparison logic in that class, though.

In a very similar vein to this, you can also simply use the Map.Entry::getValue as well:

Map<String, Integer> sortedMap = unsortedMap.entrySet().stream()
        .sorted(Comparator.comparingInt(Map.Entry::getValue))
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (a, b) -> { throw new AssertionError(); },
                LinkedHashMap::new
        ));

sortedMap.entrySet().forEach(System.out::println);
Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

This also returns:

John=21
Sydney=24
Mark=31
Maria=34

This one is functionally the exact same as the previous one, as Map.Entry.comparingByValue() uses the getValue() method to compare entries anyway.

Sort HashMap in Descending Order

Now, let's sort the unsorted HashMap in descending order instead. The only difference you need to make is the Lambda Expression we've supplied to the Comparator.comparingInt() method - we'll just use -e.getValue() instead:

Map<String, Integer> sortedMap = unsortedMap.entrySet().stream()
        .sorted(Comparator.comparingInt(e -> -e.getValue()))
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (a, b) -> { throw new AssertionError(); },
                LinkedHashMap::new
        ));

sortedMap.entrySet().forEach(System.out::println);

This results in:

Maria=34
Mark=31
Sydney=24
John=21

This is the added benefit of using this approach, instead of either Map.Entry.comparingByValue() or Map.Entry::getValue. You can easily switch between descending and ascending order.

Conclusion

In this tutorial, we've gone over how to sort a Java HashMap by Value. We've used Java 8 Streams with the LinkedHashMap class to achieve this functionality, both to sort by ascending and descending values.

Last Updated: October 3rd, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

David LandupAuthor

Entrepreneur, Software and Machine Learning Engineer, with a deep fascination towards the application of Computation and Deep Learning in Life Sciences (Bioinformatics, Drug Discovery, Genomics), Neuroscience (Computational Neuroscience), robotics and BCIs.

Great passion for accessible education and promotion of reason, science, humanism, and progress.

Make Clarity from Data - Quickly Learn Data Visualization with Python

Learn the landscape of Data Visualization tools in Python - work with Seaborn, Plotly, and Bokeh, and excel in Matplotlib!

From simple plot types to ridge plots, surface plots and spectrograms - understand your data and learn to draw conclusions from it.

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms