Java 8 – How to sort a Map

sorting

Java 8 Stream examples to sort a Map, by keys or by values.

1. Quick Explanation

Steps to sort a Map in Java 8.

  1. Convert a Map into a Stream
  2. Sort it
  3. Collect and return a new LinkedHashMap (keep the order)

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

P.S By default, Collectors.toMap will returns a HashMap

2. Sort by Keys

SortByKeyExample.java

package com.mkyong.test;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class SortByKeyExample {

    public static void main(String[] argv) {

        Map<String, Integer> unsortMap = new HashMap<>();
        unsortMap.put("z", 10);
        unsortMap.put("b", 5);
        unsortMap.put("a", 6);
        unsortMap.put("c", 20);
        unsortMap.put("d", 1);
        unsortMap.put("e", 7);
        unsortMap.put("y", 8);
        unsortMap.put("n", 99);
        unsortMap.put("g", 50);
        unsortMap.put("m", 2);
        unsortMap.put("f", 9);

        System.out.println("Original...");
        System.out.println(unsortMap);

        // sort by keys, a,b,c..., and return a new LinkedHashMap
        // toMap() will returns HashMap by default, we need LinkedHashMap to keep the order.
        Map<String, Integer> result = unsortMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));


        // Not Recommend, but it works.
        //Alternative way to sort a Map by keys, and put it into the "result" map
        Map<String, Integer> result2 = new LinkedHashMap<>();
        unsortMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .forEachOrdered(x -> result2.put(x.getKey(), x.getValue()));

        System.out.println("Sorted...");
        System.out.println(result);
        System.out.println(result2);

    }

}

Output

Original...
{a=6, b=5, c=20, d=1, e=7, f=9, g=50, y=8, z=10, m=2, n=99}

Sorted...
{a=6, b=5, c=20, d=1, e=7, f=9, g=50, m=2, n=99, y=8, z=10}
{a=6, b=5, c=20, d=1, e=7, f=9, g=50, m=2, n=99, y=8, z=10}

3. Sort by Values

SortByValueExample.java

package com.mkyong.test;

package com.mkyong;

import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class SortByValueExample {

    public static void main(String[] argv) {

        Map<String, Integer> unsortMap = new HashMap<>();
        unsortMap.put("z", 10);
        unsortMap.put("b", 5);
        unsortMap.put("a", 6);
        unsortMap.put("c", 20);
        unsortMap.put("d", 1);
        unsortMap.put("e", 7);
        unsortMap.put("y", 8);
        unsortMap.put("n", 99);
        unsortMap.put("g", 50);
        unsortMap.put("m", 2);
        unsortMap.put("f", 9);

        System.out.println("Original...");
        System.out.println(unsortMap);

        //sort by values, and reserve it, 10,9,8,7,6...
        Map<String, Integer> result = unsortMap.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));

						
        //Alternative way
        Map<String, Integer> result2 = new LinkedHashMap<>();
        unsortMap.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .forEachOrdered(x -> result2.put(x.getKey(), x.getValue()));

        System.out.println("Sorted...");
        System.out.println(result);
        System.out.println(result2);

    }
}

Output

Original...
{a=6, b=5, c=20, d=1, e=7, f=9, g=50, y=8, z=10, m=2, n=99}

Sorted...
{n=99, g=50, c=20, z=10, f=9, y=8, e=7, a=6, b=5, m=2, d=1}
{n=99, g=50, c=20, z=10, f=9, y=8, e=7, a=6, b=5, m=2, d=1}
Note
Not using Java 8? Try this classic way to sort a Map in Java.

References

  1. How to sort a Map in Java
  2. LinkedHashMap JavaDoc
  3. Collectors.toMap() JavaDoc
  4. More Fun with Wildcards
  5. Collections.sort() signature
  6. Difference between and in Java

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
Thach
Guest
Thach

Map result = unsortMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));

I am sorry but what does it mean (oldValue, newValue) -> oldValue ?

rancho
Guest
rancho

Map result = unsortMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
won’t cause any compile problems, but the keys might be duplicate, in which case throw
“java.lang.IllegalStateException: Duplicate key” exception.
by using extra arguments “(oldValue, newValue) -> oldValue, LinkedHashMap::new”
method will be overloaded as “R collect(Collector collector);”
this will make sure mergeFunction (oldValue, newValue) -> oldValue be passed in, and duplicate keys removed.

Anton Balaniuc
Guest
Anton Balaniuc
Hi Mkyong, Please note that is not recommended to use foreach to populate other collection. The collect operation is more preferable in this case. unsortedMap.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new)); instead of //sort by key, a,b,c…, and put it into the “result” map unsortMap.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .forEachOrdered(x -> result.put(x.getKey(), x.getValue())); Best Regards, Anton
ganesh bn
Guest
ganesh bn

Please expline deeply

mkyong
Guest
mkyong

The source code should be self-explanatory, which lines need to explain more?

karthikeyan
Guest
karthikeyan

How to handle null key/value here?

Carol
Guest
Carol

Thanks, very clear.

Conor
Guest
Conor

Wow this is very powerful! Can you comment on the time complexity required to do such an operation? Your code is pretty self-explanatory but I am unsure about the underlying mechanisms Java is using to do the sorting.

Bhanuprasad
Guest
Bhanuprasad

Hi mkyong,
just need small help in my scenario like
map(user0,value
user1,value
user2,value
passo,value
pass1,value
pass2,value
url0,value
url1,value
url2,value)

I want the output as
map(user0,value
pass0,value
url0,value
user1,value
pass1,value
url1,value
…..)
like this could you please help me with the logic.
I used tree map already which is not working as expected.