我有一个班级列表ProductDto
public class ProductDto {
private String Id;
private String status;
private Booker booker;
private String category;
private String type;
}
我想要一张如下地图: -
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;
})
));
如果有人知道通过使用流来做到这一点的好方法,请分享!
答案 0 :(得分:16)
从面向对象的角度看,有一张地图地图的地图是有问题的,因为你可能看起来缺少一些抽象(即你可以创建一个封装结果的类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
收集器,以便它返回{{ 1}}而不是Booker
s。
如果您只需要一个productDto
个实例而不是Booker
作为最内层地图的值,则需要一种方法来 reduce {{1}实例,即通过关联操作将多个实例转换为一个实例(累积某些属性的总和是最常见的一个)。
对于第二种方法,拥有List<Booker>
可能被视为不良做法甚至是纯粹的邪恶。因此,您可以只拥有一个列表映射,而不是拥有列表映射映射的映射,其中的键表示要分组的3个属性的组合。
最简单的方法是使用Booker
作为密钥,因为列表已经提供Map<String, Map<String, Map<String, List<Booker>>>>
和List
个实现:
hashCode
如果您使用的是Java 9+,则可以使用List.of
代替equals
,因为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())))));
会返回完全不可变且高度优化的列表。