How to Sort Map in Java using Streams

This tutorial decribes how to sort a map in Java using streams.

1. Create and Print the Map

Let us first create a map which contains key as id and value as names. We will print all the entries in the map using forEach method

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.demo;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,String> names = new HashMap<>();
       names.put(2,"Jim");
       names.put(11,"Tim");
       names.put(41,"Jane");
       names.put(5,"Mary");
       names.put(3,"Zack");
       //print the map
        names.entrySet().stream().forEach(System.out::println);

    }


}

Below output shows key and value printed in random order which is not sorted

1
2
3
4
5
2=Jim
3=Zack
5=Mary
41=Jane
11=Tim

Below video also showcases how to sort a map using streams.

2. Sort the map by Key using Streams

Now we will sort the map using key which is id

We can do this by passing Map.Entry.comparingByKey() as an argument to sorted method

 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
package com.demo;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,String> names = new HashMap<>();
       names.put(2,"Jim");
       names.put(11,"Tim");
       names.put(41,"Jane");
       names.put(5,"Mary");
       names.put(3,"Zack");
       //print the map
      //  names.entrySet().stream().forEach(System.out::println);
        names.entrySet().stream().sorted(Map.Entry.comparingByKey())
                .forEach(System.out::println);


    }


}

In the below output we can keys are sorted in ascending order as expected

1
2
3
4
5
2=Jim
3=Zack
5=Mary
11=Tim
41=Jane

3. Sort by Key in descending order using Streams

To print the sorting order in reverse order we need to pass Comparator.reverseOrder() to Map.Entry.comparingByKey() method as an argument as shown 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
package com.demo;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,String> names = new HashMap<>();
       names.put(2,"Jim");
       names.put(11,"Tim");
       names.put(41,"Jane");
       names.put(5,"Mary");
       names.put(3,"Zack");
       //print the map
      //  names.entrySet().stream().forEach(System.out::println);
        names.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
                .forEach(System.out::println);


    }


}

In the below output we can keys are sorted in reverse order(descending) as expected

1
2
3
4
5
41=Jane
11=Tim
5=Mary
3=Zack
2=Jim

4. Sort by Value using Streams

In similar way we can sort the map using values

In this case we need to pass Map.Entry.comparingByValue() as an argument to sorted method.

 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
package com.demo;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,String> names = new HashMap<>();
       names.put(2,"Jim");
       names.put(11,"Tim");
       names.put(41,"Jane");
       names.put(5,"Mary");
       names.put(3,"Zack");
       //print the map
      //  names.entrySet().stream().forEach(System.out::println);
        names.entrySet().stream().sorted(Map.Entry.comparingByValue())
                .forEach(System.out::println);


    }


}

In the below output values are printed in ascending order

1
2
3
4
5
41=Jane
2=Jim
5=Mary
11=Tim
3=Zack

5. Sort by Value in descending order using Streams

To print the sorting order in reverse order we need to pass Comparator.reverseOrder() to Map.Entry.comparingByValue() method as an argument as shown 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
package com.demo;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,String> names = new HashMap<>();
       names.put(2,"Jim");
       names.put(11,"Tim");
       names.put(41,"Jane");
       names.put(5,"Mary");
       names.put(3,"Zack");
       //print the map
      //  names.entrySet().stream().forEach(System.out::println);
        names.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .forEach(System.out::println);


    }


}

In the below output values are printed in reverse order(descending)

1
2
3
4
5
3=Zack
11=Tim
5=Mary
2=Jim
41=Jane

6. Sort by key/value which is custom object using Streams

In the below example we have Employee object as value to the map.

In such scenarios we need to pass Comparator.comparing() as an argument to Map.Entry.comparingByValue() method.

Comparator.comparing(Employee::getName) contains sort key which must be using to sort the map.

Here getter method of employee object getName will extract the key which is required for sorting.

 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
package com.demo;

import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,Employee> employees = new HashMap<>();

       employees.put(4, new Employee("harish",30));
       employees.put(2, new Employee("jim",23));
       employees.put(1, new Employee("tim",55));
       employees.put(5, new Employee("tim",34));
       employees.put(3, new Employee("zaack",45));

        employees.entrySet().stream().
                sorted(Map.Entry.comparingByValue(Comparator.comparing(Employee::getName)))
                .forEach(System.out::println);
    }
}

class Employee {
    private String name;
    private int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

In the below output you can map is sorted based on name of employee object in asecending order

1
2
3
4
5
4=Employee{name='harish', age=30}
2=Employee{name='jim', age=23}
1=Employee{name='tim', age=55}
5=Employee{name='tim', age=34}
3=Employee{name='zaack', age=45}

7. Sort by key/value in descending order which is custom object using Streams

To sort the custom object in reverse order we need to pass Comparator.reverseOrder() as an second argument to Comparator.comparing method

 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
package com.demo;

import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

public class App {

    public static void main(String[] args) throws IOException {

       Map<Integer,Employee> employees = new HashMap<>();

       employees.put(4, new Employee("harish",30));
       employees.put(2, new Employee("jim",23));
       employees.put(1, new Employee("tim",55));
       employees.put(5, new Employee("tim",34));
       employees.put(3, new Employee("zaack",45));

        employees.entrySet().stream().
                sorted(Map.Entry.comparingByValue(Comparator.comparing(Employee::getName,Comparator.reverseOrder())))
                .forEach(System.out::println);
    }
}

class Employee {
    private String name;
    private int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

In the below output map is sorted based on employee name in reverse order based on employee name

1
2
3
4
5
3=Employee{name='zaack', age=45}
1=Employee{name='tim', age=55}
5=Employee{name='tim', age=34}
2=Employee{name='jim', age=23}
4=Employee{name='harish', age=30}

I hope this tutorial was helpful in explaining how to sort a map using streams in Java 8