Vin*_*ati 9 java java-8 java-stream
我有一个班级列表说 ProductDto
public class ProductDto {
private String Id;
private String status;
private Booker booker;
private String category;
private String type;
}
Run Code Online (Sandbox Code Playgroud)
我想要一张地图如下: -
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;
})
));
Run Code Online (Sandbox Code Playgroud)
如果有人知道通过使用流来做到这一点的好方法,请分享!
Fed*_*ner 20
从面向对象的角度看,有一张地图地图的地图是有问题的,因为你可能看起来缺少一些抽象(即你可以创建一个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())))));
Run Code Online (Sandbox Code Playgroud)
如你所见,结果是一个Map<String, Map<String, Map<String, List<Booker>>>>.这是因为可能存在多个ProductDto具有相同(status, category, type)组合的实例.
此外,由于您需要Booker实例而不是ProductDto实例,我正在调整最后一个groupingBy收集器,以便它返回Bookers而不是productDtos.
如果您只需要一个Booker实例而不是a List<Booker>作为最内层映射的值,则需要一种方法来减少 Booker实例,即通过关联操作将多个实例转换为一个实例(累积某些属性的总和最多)常见的一个).
对于第二种方法,有Map<String, Map<String, Map<String, List<Booker>>>>可能被视为不良做法甚至是纯粹的邪恶.因此,您可以只拥有一个列表映射,而不是拥有列表映射映射的映射,其中的键表示要分组的3个属性的组合.
最简单的方法是使用a List作为键,因为列表已经提供hashCode和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())))));
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Java 9+,则可以使用List.of而不是Arrays.asList,因为List.of返回完全不可变且高度优化的列表.
| 归档时间: |
|
| 查看次数: |
1246 次 |
| 最近记录: |