【问题标题】:Sorting Entries in Map by Size of Lists按列表大小对 Map 中的条目进行排序
【发布时间】:2021-10-07 22:44:25
【问题描述】:

我有一个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);

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

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

【问题讨论】:

  • LinkedHashMap 没有实现 SortedMap。如果你可以切换到使用 TreeMap,你可以在其上使用 Collections.sort()。
  • 事实上,您将单个列表从地图中拉出,并尝试对它们进行排序,这无助于您重新排列地图内的列表。

标签: java list sorting dictionary


【解决方案1】:

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

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]

【讨论】:

    【解决方案2】:

    这不会做你想做的事:

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

    您的错误是由于类型:

    Map.Entry<String, List<String>> entry
    

    这意味着entry.getValue() 返回一个List&lt;String&gt;,并且List.sort(Comparator&lt;T&gt;) 仅适用于Comparator&lt;String&gt;,因为T = String

    如果你想按List的大小排序,你将不得不失去类别:

    List<List<String>> list = new ArrayList<>(map.values());
    list.sort((a1, a2) -> a2.size() - a1.size());
    

    如果你需要保持类别,那么你需要一个中间类型来保持映射:

    List<Map.Entry<String, List<String>>> list = new ArrayList<>(map.entrySet());
    list.sort((a1, a2) -> a2.getValue().size() - a1.getValue()..size());
    

    请注意,我使用的是 List 而不是修改 Map:并非所有地图都允许排序,而那些允许排序 (SortedMap) 的地图大多按键排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-09
      • 2021-06-06
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多