如何根据其Collection值的大小对Map进行排序?

时间:2015-06-15 19:06:28

标签: java sorting java-8 java-stream

我有HashMap这样:

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"));

我想根据列表值的大小按升序对地图进行排序。我怎么能这样做?

在这种情况下,我希望按键订购加拿大,印度,美国。

3 个答案:

答案 0 :(得分:15)

HashMap没有保证的迭代顺序,因此您需要收集到LinkedHashMap才能使排序有意义。

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
    )); 

抛出AssertionError,因为组合函数是only used on parallel streams,我们没有使用它。

如果您发现它更具可读性,也可以使用comparingByValue

Map<String, List<String>> sorted = map.entrySet().stream()
    .sorted(comparingByValue(comparingInt(List::size)))
    // ... as above

答案 1 :(得分:1)

你有两个问题。

  1. 地图不支持排序。

  2. SortedMap不支持对仅按键排序的值进行排序。

  3. 因此使用Map或SortedMap并不能帮助您。您需要做的是迭代映射并将每个Entry<String, ArrayList<String>>放入一个集合(如List)中,然后使用自定义比较对列表进行排序。请参阅此示例TreeMap sort by value或此示例Sorting LinkedHashMap

答案 2 :(得分:1)

您可以简单地将哈希映射到 Pair() 的列表,然后对列表进行排序

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")