根据另一个地图中的值对Java Map进行排序

问题描述 投票:-2回答:1

作为输入,我有对象列表,每个对象都有名称和地图:

1)
  Name: m1

  Map: {"c1": 3,
 "c2": 24
 "c3": 12}

2) Name: m2

Map: {"c1": "A",
 "c2": "B",
 "c3": "C"}

3) Name: m3

Map: {"c1": 3.4,
 "c2": 4.6,
 "c3": 12.3}

我需要作为输出,我需要根据名称为m1的地图中的值对所有3个地图进行排序。

首先,我想按降序排序值对象#1(m1)的映射(我可以在这里使用LinedHashMap):

{"c1": 3, "c2": 24, "c3": 12}  =>  {"c2": 24, "c3": 12, "c1": 3} 

现在,我想要对象#2的地图元素和对象#3的地图,也要按相同的键顺序排序 - C2,C3,C1。所以基本上我想重新排序2个映射,以便顺序是C2,C3,C1(与m1中的顺序相同),而不是C1,C2,C3。

我怎样才能以最优雅的方式做到这一点?我有一些解决方案 - 但它们很混乱,还有很多额外的步骤。

如果这很重要:此列表将始终只有3个对象。 Map中的元素数量可以不同,但​​地图中的键在3个地图中始终相同

java dictionary linked-list linkedhashmap
1个回答
1
投票

所以你知道如何按值排序Map,也许通过阅读这个答案:Sort a Map by values (Java),答案的Java 8版本是:

m1sorted = m1.entrySet()
             .stream()
             .sorted(Map.Entry.comparingByValue(Collections.reverseOrder()))
             .collect(Collectors.toMap(
               Map.Entry::getKey,
               Map.Entry::getValue,
               (e1, e2) -> e1,
               LinkedHashMap::new
             ));

那你怎么用m2的值来排序m3m1

简单:您向Comparator提供sorted(),用于比较值,例如:

.sorted(Comparator.comparing(e -> m1.get(e.getKey())).reversed())

您可能必须明确指定e的类型,因为推理引擎可能会丢失:comparing((Entry<String, String> e) ->

如果你不喜欢Comparator.comparing()reversed(),以及推理问题,你可以使用lambda。

以下是所有代码,作为概念证明:

Map<String, Integer> m1 = new HashMap<>();
m1.put("c1", 3);
m1.put("c2", 24);
m1.put("c3", 12);

Map<String, String> m2 = new HashMap<>();
m2.put("c1", "A");
m2.put("c2", "B");
m2.put("c3", "C");

Map<String, Double> m3 = new HashMap<>();
m3.put("c1", 3.4);
m3.put("c2", 4.6);
m3.put("c3", 12.3);
Map<String, Integer> m1s =
        m1.entrySet()
          .stream()
          .sorted((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()))
          .collect(Collectors.toMap(Map.Entry::getKey,
                                    Map.Entry::getValue,
                                    (e1, e2) -> e1,
                                    LinkedHashMap::new));

Map<String, String> m2s =
        m2.entrySet()
          .stream()
          .sorted((e1, e2) -> Integer.compare(m1.get(e2.getKey()), m1.get(e1.getKey())))
          .collect(Collectors.toMap(Map.Entry::getKey,
                                    Map.Entry::getValue,
                                    (e1, e2) -> e1,
                                    LinkedHashMap::new));

Map<String, Double> m3s =
        m3.entrySet()
          .stream()
          .sorted((e1, e2) -> Integer.compare(m1.get(e2.getKey()), m1.get(e1.getKey())))
          .collect(Collectors.toMap(Map.Entry::getKey,
                                    Map.Entry::getValue,
                                    (e1, e2) -> e1,
                                    LinkedHashMap::new));
System.out.println(m1s);
System.out.println(m2s);
System.out.println(m3s);

产量

{c2=24, c3=12, c1=3}
{c2=B, c3=C, c1=A}
{c2=4.6, c3=12.3, c1=3.4}

注意e2e1如何在lambda中反转导致降序。

当然,使用Java的面向对象特性并且只有一个Map对于具有三个字段的值的对象会好得多。

© www.soinside.com 2019 - 2024. All rights reserved.