Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I sort a Map based upon on the size of its Collection values?

I have a HashMap like this:

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

map.put("USA", Arrays.asList("CA","IA","IL"));
map.put("India", Arrays.asList("MUM","CAL"));
map.put("Canada", Arrays.asList("TOR"));

I want to sort the map depending on the size of the list value, in ascending order. How can I do that?

In this case, I would like the keys to be ordered Canada, India, USA.

like image 354
Md Johirul Islam Avatar asked Jun 15 '15 19:06

Md Johirul Islam


2 Answers

HashMap does not have a guaranteed iteration order so you will need to collect to a LinkedHashMap in order for the sorting to be meaningful.

import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.toMap;

Map<String, List<String>> sorted = map.entrySet().stream()
    .sorted(comparingInt(e -> e.getValue().size()))
    .collect(toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (a, b) -> { throw new AssertionError(); },
        LinkedHashMap::new
    )); 

The AssertionError is thrown because a combiner function is only used on parallel streams, which we are not using.

You can also use comparingByValue if you find it more readable:

import static java.util.Map.Entry.comparingByValue;

Map<String, List<String>> sorted = map.entrySet().stream()
    .sorted(comparingByValue(comparingInt(List::size)))
    // ... as above
like image 51
Misha Avatar answered Nov 08 '22 08:11

Misha


You have two problems.

  1. Map doesn't support sorting.

  2. SortedMap doesn't support sorting on values only sorting on keys.

As a result of this using a Map or SortedMap isn't going to help you. What you need to do is iterate over you map and put each Entry<String, ArrayList<String>> into a collection such as a List and then sort the list with a custom compare. See this example TreeMap sort by value or this example Sorting LinkedHashMap

like image 1
bhspencer Avatar answered Nov 08 '22 09:11

bhspencer