Reputation: 5162
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.
Upvotes: 13
Views: 14050
Reputation: 21981
public static <K,V extends Collection> Map<K,V> sortMap(Map<K,V> map){
return map.entrySet().stream()
.sorted((e1, e2) -> Integer.compare(e2.getValue().size(), e1.getValue().size()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
Upvotes: 2
Reputation: 41
You can simply map the hash to list of Pair() and then sort the list
val map: MutableMap<String, List<String>> = HashMap()
map["USA"] = listOf("CA", "IA", "IL")
map["India"] = listOf("MUM", "CAL")
map["Canada"] = listOf("TOR")
val sortedPairs = map.map { Pair(it.key, it.value) }.sortedBy { it.second.size }.toMap()
println("sorted List: $sortedPairs")
Upvotes: 1
Reputation: 28133
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
Upvotes: 24
Reputation: 13560
You have two problems.
Map doesn't support sorting.
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
Upvotes: 1