首页 > 解决方案 > 按列表大小对 Map 中的条目进行排序

问题描述

我有一个Map由一个String和一个对应的组成List。这些列表有不同的大小:

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

List<String> l1 = new ArrayList<>();
List<String> l2 = new ArrayList<>();
List<String> l3 = new ArrayList<>();

l1.add("Str1");
l1.add("Str2");
l2.add("Str1");
l2.add("Str2");
l2.add("Str3");
l3.add("Str1");

map.put("Category A", l1);
map.put("Category B", l2);
map.put("Category C", l3);

我想按sMap的大小对Lists 的条目进行降序排序。所以在我的例子中,最终结果应该是:

Category B: Str1, Str2, Str3
Category A: Str1, Str2
Category C: Str1

我试过了:

for (Map.Entry<String, List<String>> entry : map.entrySet()) {
    entry.getValue().sort(new Comparator<String>() {
        public int compare(ArrayList a1, ArrayList a2) {
            return a2.size() - a1.size();
        }
});

但我得到:

java: <anonymous com.app.class> is not abstract and does not override abstract method compare(java.lang.String,java.lang.String) in java.util.Comparator

标签: javalistsortingdictionary

解决方案


您可以引入另一个 Map<K, V> 实例(这样可以保留插入顺序,例如LinkedHashMap<K, V>),并按照比较器规定的顺序将条目插入其中:

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

List<String> l1 = new ArrayList<>();
List<String> l2 = new ArrayList<>();
List<String> l3 = new ArrayList<>();

l1.add("Str1");
l1.add("Str2");
l2.add("Str1");
l2.add("Str2");
l2.add("Str3");
l3.add("Str1");

map.put("Category A", l1);
map.put("Category B", l2);
map.put("Category C", l3);


LinkedHashMap<String, List<String>> descByValues = new LinkedHashMap<>();

map.entrySet()
        .stream()
        .sorted((e1, e2) -> e2.getValue().size() - e1.getValue().size())
        .forEachOrdered(x -> descByValues.put(x.getKey(), x.getValue()));

接着:

descByValues
        .forEach((k, v) -> System.out.println(k + ", " + v));

将输出:

Category B, [Str1, Str2, Str3]
Category A, [Str1, Str2]
Category C, [Str1]

推荐阅读