gpt4 book ai didi

java - 如何使用 Collectors.groupingBy 创建嵌套 map ?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:31:35 24 4
gpt4 key购买 nike

我有一个类(class)列表说 ProductDto

public class ProductDto {
private String Id;
private String status;
private Booker booker;
private String category;
private String type;
}

我想要一个如下所示的 map :-

Map<String,Map<String,Map<String,Booker>>

属性映射如下:

Map<status,Map<category,Map<type,Booker>

我知道使用 Collectors.groupingBy 可以轻松完成一级分组,没有任何麻烦。 .

我尝试将它用于嵌套级别,但当相同的值开始出现在作为键的字段时,它对我来说失败了。

我的代码如下:-

 list.stream()
.collect(Collectors.groupingBy(
(FenergoProductDto productDto) ->
productDto.getStatus()
,
Collectors.toMap(k -> k.getProductCategory(), fProductDto -> {
Map<String, Booker> productTypeMap = new ProductTypes();
productTypeMap.put(fProductDto.getProductTypeName(),
createBooker(fProductDto.getBookingEntityName()));
return productTypeMap;
})
));

如果有人知道使用流来执行此操作的好方法,请分享!

最佳答案

摘要/简短讨论

从面向对象的角度来看,拥有 map 的 map 是值得怀疑的,因为它似乎缺少一些抽象(即您可以创建一个类 Result 来封装嵌套分组的结果).但是,如果仅从纯面向数据的方法考虑,这是完全合理的。

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


面向数据的方法

对于第一种方法,您可以嵌套 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())))));

如您所见,结果是 Map<String, Map<String, Map<String, List<Booker>>>> .这是因为可能有不止一个 ProductDto具有相同 (status, category, type) 的实例组合。

另外,根据需要Booker实例而不是 ProductDto实例,我正在改编最后一个 groupingBy收集器,以便它返回 Booker s 而不是 productDto秒。


关于减少

如果你只需要一个Booker实例而不是 List<Booker>作为最内层 map 的值,您需要一种方法来减少 Booker实例,即通过关联操作将许多实例转换为一个实例(累积某些属性的总和是最常见的一个)。


面向对象的友好方法

对于第二种方法,有一个 Map<String, Map<String, Map<String, List<Booker>>>>可能被视为不良做法,甚至被视为纯粹的邪恶。因此,您可以只有一个列表映射,而不是拥有列表映射的映射,其键代表您要分组的 3 个属性的组合。

最简单的方法是使用 List作为关键,因为列表已经提供了 hashCodeequals实现:

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())))));

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

关于java - 如何使用 Collectors.groupingBy 创建嵌套 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48665084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com