Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何用流替换LinkedhashMap和HashMap?_Java_Lambda_Java Stream_Linkedhashmap_Collectors - Fatal编程技术网

Java 如何用流替换LinkedhashMap和HashMap?

Java 如何用流替换LinkedhashMap和HashMap?,java,lambda,java-stream,linkedhashmap,collectors,Java,Lambda,Java Stream,Linkedhashmap,Collectors,你能帮我把地图分类吗 我有下面的结构,我想在LinkedHashMap中按值的相反顺序在customers下组装应用程序 [{ "CUSTOMER_1": { "APP_1": "1" }, "CUSTOMER_2": { "APP_1": "2", "APP_3": "7", "APP_2": "3" } }] 我已经有了组装地图的lambda: final Map<String, Map<String, Long>>

你能帮我把地图分类吗

我有下面的结构,我想在
LinkedHashMap
中按值的相反顺序在customers下组装应用程序

[{
  "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;
                    }))
            );

如何在一个lambda中完成此操作?

在创建按结果值排序的
LinkedHashMap之前,您无法避免将值收集到映射中,但您可以将转换步骤指定为自定义收集器的finisher函数:

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))
    )));
Map organizationApps=input.stream()
.flatMap(e->e.entrySet().stream())
.collect(groupby)(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));
返回r1;
},
(映射m)->m.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)->e2,
LinkedHashMap::新建)
)));
这相当于以下(Java9+)代码

Map 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)),
(映射m)->m.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)->e2,
LinkedHashMap::新建)
)));

最后是与Java 8兼容的
flatMapping
收集器的实现,但您的自定义收集器也会执行此任务。

在创建按结果值排序的
LinkedHashMap
之前,您无法避免将值收集到映射中,但您可以将转换步骤指定为自定义收集器的finisher函数:

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))
    )));
Map organizationApps=input.stream()
.flatMap(e->e.entrySet().stream())
.collect(groupby)(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));
返回r1;
},
(映射m)->m.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)->e2,
LinkedHashMap::新建)
)));
这相当于以下(Java9+)代码

Map 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)),
(映射m)->m.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(toMap(Map.Entry::getKey,Map.Entry::getValue,(e1,e2)->e2,
LinkedHashMap::新建)
)));

最后是一个兼容Java 8的
flatMapping
收集器的实现,但是您的自定义收集器也可以完成这项工作。

这里有一个相关的问题:。重要的是,你需要在收集之前对你的流进行适当的排序。嗨,Ryan!我想我需要在组装映射后对其进行排序,因为最初我可以有两个列表,其中包含具有重复键的映射,我通过求和值来合并映射。我有以下问题:为什么需要在一个lambda中执行此操作?即使这是可能的,你可能会有真正大而丑陋的代码和平。我已经很难理解你的代码中发生了什么。IMHO lambda并不总是解决此类问题的最佳方案。如前所述,lambdas应该是一种表达,而不是一种叙述。尽管lambdas的语法简洁,但它应该准确地表达它们提供的功能。1)因为我想查看结果并将其与以下内容进行比较2)我想了解更多关于lambdas的知识可能有一些不同的方法来组织操作,但最终,在排序之前,您需要应用程序的合并/求和结果,因此我认为它将始终需要(至少)两个逻辑步骤。重要的是,你需要在收集之前对你的流进行适当的排序。嗨,Ryan!我想我需要在组装映射后对其进行排序,因为最初我可以有两个列表,其中包含具有重复键的映射,我通过求和值来合并映射。我有以下问题:为什么需要在一个lambda中执行此操作?即使这是可能的,你可能会有真正大而丑陋的代码和平。我已经很难理解你的代码中发生了什么。IMHO lambda并不总是解决此类问题的最佳方案。如前所述,lambdas应该是一种表达,而不是一种叙述。尽管lambdas的语法简洁,但它应该准确地表达它们提供的功能。1)因为我想查看结果并将其与以下内容进行比较2)我想了解更多关于lambdas的知识可能有一些不同的方法来组织操作,但最终你需要应用程序合并/求和的结果,然后才能进行排序,所以我认为它总是需要(至少)两个逻辑步骤。谢谢你,这正是我想要的!谢谢,那正是我想要的!
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))
    )));