Java 8 Lambdas flatmapping、groupingBy 和 mapping 以获取 T 和 List<K> 的 Map

标签 java lambda stream functional-java

这是我到目前为止所拥有的:

Map<Care, List<Correlative>> mapOf = quickSearchList
                .stream()
                .map(QuickSearch::getFacility)
                .collect(Collectors.flatMapping(facility -> facility.getFacilityCares().stream(),
                    Collectors.groupingBy(FacilityCare::getCare,
                        Collectors.mapping(c -> {
                            final Facility facility = new Facility();
                            facility.setId(c.getFacilityId());
                            return Correlative.createFromFacility(facility);
                        }, Collectors.toList()))));
我有一个快速搜索列表。快速搜索中的每个项目都有一个工具,如下所示:
public class QuickSearch {
  Facility facility;
}
在每个设施中,都有一个 FacilityCare 列表,如下所示:
public class Facility {
  List<FacilityCare> facilityCares;
}
最后, FacilityCare 具有 Care 属性,如下所示:
public class FacilityCare {
   Care care;
}
现在,我们的想法是将 QuickSearch 的 List 转换为 <Care, List<Correlative>> 的 Map。
在上面的示例中, mapping() 函数中的代码是伪造的。 FacilityCare 只有设施 ID 而没有设施实体。我希望在 flatMapping 中作为参数的工具对象在 mapping() 函数中再次成为我的参数,如下所示:
Collectors.mapping(c -> Correlative.createFromFacility(facility)) 
其中“facility”是与 flatMapping 中的对象相同的对象。
有没有办法实现这一目标?如果需要进一步解释,请告诉我。
编辑:
这是一个没有充分利用收集器的解决方案。
final Map<Care, List<Correlative>> mapToHydrate = new HashMap<>();

 quickSearchList
  .stream()
  .map(QuickSearch::getFacility)
  .forEach(facility -> {
    facility.getFacilityCares()
      .stream()
      .map(FacilityCare::getCare)
      .distinct()
      .forEach(care -> {
        mapToHydrate.computeIfAbsent(care, care -> new ArrayList<>());
        mapToHydrate.computeIfPresent(care, (c, list) -> {
          list.add(Correlative.createFromFacility(facility));
          return list;
        });
      });
    });
      

最佳答案

有时,流并不是最好的解决方案。情况似乎是这样,因为在沿着管道运行时您正在丢失每个 facility 实例。
相反,您可以按如下方式进行:

Map<Care, List<Correlative>> mapToHydrate = new LinkedHashMap<>();
quickSearchList.forEach(q -> {
    Facility facility = q.getFacility();
    facility.getFacilityCares().forEach(fCare -> 
        mapToHydrate.computeIfAbsent(fCare.getCare(), k -> new ArrayList<>())
                    .add(Correlative.createFromFacility(facility)));
});
这使用 Map.computeIfAbsent 的返回值(它是新创建的相关列表或已经存在的列表)。
从您的问题中不清楚为什么在将它们添加到 map 之前需要特别注意。

编辑: 从 Java 16 开始,您可能想要使用 Stream.mapMulti :
Map<Care, List<Correlative>> mapToHydrate = quickSearchList.stream()
    .map(QuickSearch::getFacility)
    .mapMulti((facility, consumer) -> facility.getFacilityCares()
        .forEach(fCare -> consumer.accept(Map.entry(fCare.getCare(), facility))))
    .collect(Collectors.groupingBy(
        e -> e.getKey(), 
        Collectors.mapping(
            e -> Correlative.createFromFacility(e.getValue()),
            Collectors.toList())));

关于Java 8 Lambdas flatmapping、groupingBy 和 mapping 以获取 T 和 List<K> 的 Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64326329/

相关文章:

lambda - 如何获取由 lambda 产生的方法的名称

mongodb 更改流 java

JAVA json架构2 POJO

Java显示应用程序版本号的最佳实践

python - 在函数定义中正确使用 lambda

c# - 如果不使用 lambda 表达式,这个 Parallel.ForEach 循环将如何完成?

c# - 流.读 : EOF vs 0 count

javascript - 文件下载完成后运行文件

java - 创建排行榜?

JavaEE 8、Tomcat 8.5、错误状态 404