Java 如何使用Collectors.groupingBy创建嵌套映射?

Java 如何使用Collectors.groupingBy创建嵌套映射?,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个班级名单,比如说ProductDto public class ProductDto { private String Id; private String status; private Booker booker; private String category; private String type; } 我想要一张地图,如下所示:- Map{ Map productTypeMap=新的ProductTypes(); productTyp

我有一个班级名单,比如说
ProductDto

public class ProductDto {
    private String Id;
    private String status;
    private Booker booker;
    private String category;
    private String type;
}
我想要一张地图,如下所示:-

Map{
Map productTypeMap=新的ProductTypes();
productTypeMap.put(fpProductDTO.getProductTypeName(),
createBooker(fProductDto.getBookingEntityName());
返回productTypeMap;
})
));
如果有人知道一个很好的方法来使用流,请分享

摘要/简要讨论 从面向对象的角度来看,拥有一个映射映射的映射是有问题的,因为您似乎缺少某种抽象(即,您可以创建一个类
Result
,该类封装嵌套分组的结果)。然而,如果仅从纯面向数据的方法考虑,这是完全合理的

因此,我在这里介绍了两种方法:第一种方法是纯面向数据的(使用嵌套的
groupingBy
调用,因此使用嵌套映射),而第二种方法更为面向对象,并且在抽象分组标准方面做得更好。只需选择一个更能代表您的意图和编码标准/传统的,更重要的是,选择您最喜欢的


面向数据的方法 对于第一种方法,您只需嵌套
groupingBy
调用:

Map<String, Map<String, Map<String, List<Booker>>>> result = list.stream()
    .collect(Collectors.groupingBy(ProductDto::getStatus,
             Collectors.groupingBy(ProductDto::getCategory,
             Collectors.groupingBy(ProductDto::getType,
                 Collectors.mapping(
                         ProductDto::getBooker,
                         Collectors.toList())))));

如果您使用的是Java 9+,您可以使用而不是
数组。asList
,as
List.of
返回一个完全不可变且高度优化的列表。

您需要提供一个缩减函数,指示在发生键冲突时需要做什么扫描您请在这里发布一些有用的东西或任何参考链接等?太棒了!很好的回答:)也欢迎选择:)只是一个快速的疑问!假设ProductDto::getBooker有3个属性a、b和c,我们需要填充这些属性,而不是将它们收集到列表中。这是怎么做到的?如果我看到一张地图一张地图,我会责怪并怒视责任人。@Michael nested maps在特定情况下是完全合法的。在我们公司,我们使用多级映射来实现快速访问和低内存占用数据projections@epol我没有说所有的嵌套贴图。我说的是3级(或更多)。它们很难推理,也很难使用,尤其是在键类型相同的情况下。写一些不可读的东西很少有性能上的理由。在维护多个索引时,几乎总有比疯狂使用地图更好的策略。这台引擎很好
Map<String, Map<String, Map<String, List<Booker>>>> result = list.stream()
    .collect(Collectors.groupingBy(ProductDto::getStatus,
             Collectors.groupingBy(ProductDto::getCategory,
             Collectors.groupingBy(ProductDto::getType,
                 Collectors.mapping(
                         ProductDto::getBooker,
                         Collectors.toList())))));
Map<List<String>, List<Booker>> result = list.stream()
    .collect(Collectors.groupingBy(
         dto -> Arrays.asList(dto.getStatus(), dto.getCategory(), dto.getType()),
         Collectors.mapping(
                 ProductDto::getBooker,
                 Collectors.toList())))));