代码之家  ›  专栏  ›  技术社区  ›  Pasha

如何用流替换LinkedhashMap和HashMap?

  •  0
  • Pasha  · 技术社区  · 6 年前

    你能帮我整理一下我的行李吗 Map

    我有以下结构,我想在一个 LinkedHashMap 按值的倒序排列。

    [{
      "CUSTOMER_1": {
        "APP_1": "1"
      },
      "CUSTOMER_2": {
        "APP_1": "2",
        "APP_3": "7",
        "APP_2": "3"
      }
    }]
    

    我已经有了一个组装地图的lambda:

     final Map<String, Map<String, Long>> organizationApps = taskHandles.stream().map(this::mapPayload)
                .flatMap(e -> e.entrySet().stream())
                .collect(groupingBy(Map.Entry::getKey, of(HashMap::new,
                        (r, t) -> t.getValue().forEach((k, v) -> r.merge(k, v, Long::sum)),
                        (r1, r2) -> {
                            r2.forEach((v1, v2) -> r1.merge(v1, v2, Long::sum));
                            return r1;
                        }))
                );
    

    我现在需要的是替换 organizationApps 表示为的值 HashMap LinkedHashMap公司 把这些值放到 LinkedHashMap公司 以适当的顺序。

    我怎么能在lambda做呢?

    升级版本:

    我可以通过以下代码实现必要的输出:

        final Map<String, Map<String, Long>> organizationApps = taskHandles.stream().map(this::mapPayload)
                .flatMap(e -> e.entrySet().stream())
                .collect(groupingBy(Map.Entry::getKey, of(HashMap::new,
                        (r, t) -> t.getValue().forEach((k, v) -> r.merge(k, v, Long::sum)),
                        (r1, r2) -> {
                            r2.forEach((v1, v2) -> r1.merge(v1, v2, Long::sum));
                            return r1;
                        }))
                );
    
        organizationApps.forEach((key, value) -> {
            final Map<String, Long> sorted = value.entrySet()
                    .stream()
                    .sorted(reverseOrder(Map.Entry.comparingByValue()))
                    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
                            LinkedHashMap::new));
            organizationApps.put(key, sorted);
        });
    

    我怎么能在一个lambda里做到呢?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Holger    6 年前

    在创建映射之前,不能避免将值收集到映射中 LinkedHashMap 分页装订器

    Map<String, Map<String, Long>> organizationApps = input.stream()
        .flatMap(e -> e.entrySet().stream())
        .collect(groupingBy(Map.Entry::getKey, Collector.of(HashMap::new,
            (r, t) -> t.getValue().forEach((k, v) -> r.merge(k, v, Long::sum)),
            (r1, r2) -> {
                r2.forEach((v1, v2) -> r1.merge(v1, v2, Long::sum));
                return r1;
            },
            (Map<String, Long> m) -> m.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
                    LinkedHashMap::new))
        )));
    

    相当于下面的(Java9+)代码

    Map<String, Map<String, Long>> organizationApps = input.stream()
        .flatMap(m -> m.entrySet().stream())
        .collect(groupingBy(Map.Entry::getKey, collectingAndThen(flatMapping(
                t -> t.getValue().entrySet().stream(),
                toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum)),
            (Map<String, Long> m) -> m.entrySet().stream()
                .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
                .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
                    LinkedHashMap::new))
        )));
    

    结束时 this answer flatMapping 收集器,但您的自定义收集器也会完成此工作。