集合(Map,List)分组:多属性进行分组
一、List 实体字段分组
1. 根据单一字段进行分组:
Map<Integer, List<SomeEntity>> detailTypeMap = SomeEntityS.stream().collect(Collectors.groupingBy(SomeEntity::getSomeProperty));
2. 根据日期字段的 yyyy-MM 进行分组:
Map<String, List<SomeEntity>> monthMap = someEntityList.stream().collect(Collectors.groupingBy(p -> cn.hutool.core.date.DateUtil.format(p.getOrderTime(), "yyyy-MM")));
3.1 根据 Entigy多个字段,拼成一个 进行分组:
Map<String, Map<Integer, List<SomeEntity>>> someEntityGroup = someEntityList.stream().collect(Collectors.groupingBy(SomeEntity::getSomePropertyOne, Collectors.groupingBy(SomeEntity::getSomePropertyTwo)));
3.2 根据 Entigy多个字段,分开进行分组:
Map<Integer, Map<Integer, Map<Integer, List<SomeEntity>>>> someEntityGroup = someEntityList.stream().collect(
Collectors.groupingBy(SomeEntity::getSomePropertyOne,
Collectors.groupingBy(SomeEntity::getSomePropertyTwo,
Collectors.groupingBy(SomeEntity::getSomePropertyThree))));
3.3 根据 多字段分组,引入一个包括分组字段的对象,进行分组:
1 @Data 2 @Builder 3 @EqualsAndHashCode 4 @AllArgsConstructor 5 @NoArgsConstructor 6 public class UseGroupEntity { 7 8 /** 某属性 */ 9 private Integer somePropertyOne; 10 11 /** 某属性 */ 12 private Integer somePropertyTwo; 13 14 /** 某属性 */ 15 private String somePropertyThree; 16 17 } 18 19 if(CollectionUtils.isNotEmpty(someEntityList)) { 20 someEntityGroup = someEntityList.stream().collect(Collectors.groupingBy(entity -> { 21 return UseGroupEntity.builder().shopId(entity.getSomePropertyOne()).contractInfoId(entity.getSomePropertyTwo()).settleWay(entity.getSomePropertyThree()).build(); 22 })); 23 }
二、Map 多个key进行分组
4. 根据 Map中的多个字段组合进行分组:
【写法1】:
1 Map<String, List<Map<String, String>>> mapListGroup = new HashMap(); 2 mapListGroup = someMapList.stream().collect(Collectors.groupingBy(dataMap -> { 3 String groupByField = ""; 4 StringBuilder groupKey = new StringBuilder(); 5 if(groupByBussTypeField.contains(",")){ // groupByBussTypeField 以逗号分隔的多分组字段的配置值 例 t1.name,t1.age,t2.score 6 String[] fields = groupByBussTypeField.split(","); 7 for(String field : fields){ 8 String groupField = field.substring(field.indexOf(".") + 1); // 将 t1.name,t1.age,t2.score 的点号前的前缀切去,获得单独的属性 name 和 age 和 score 9 groupKey.append(""").append(groupField).append(""").append(":").append(""").append(String.valueOf(dataMap.get(groupField))).append("""); 10 } 11 groupByField = groupKey.toString(); 12 }else{ 13 groupByField = String.valueOf(dataMap.get(groupByBussTypeField.substring(groupByBussTypeField.indexOf(".") + 1))); 14 } 15 return groupByField; 16 }));
【写法2】:
1 Map<String, List<Map<String, String>>> voucherGroup = someMapList.stream().collect(Collectors.groupingBy((e -> fetchGroupKey(someEntityProperties, e)))); 2 3 private String fetchGroupKey(List<SomeEntityProperty> someEntityProperties, Map<String, String> dataMap){ 4 // log.debug("fetchGroupKey 入参:someEntityProperties:{},dataMap:{}", JSON.toJSONString(someEntityProperties), JSON.toJSONString(dataMap)); 5 if(CollectionUtils.isEmpty(collection)){ 6 String errorMsg = "数据为为空,请核查!"; 7 log.error(errorMsg); 8 throw new RuntimeException(errorMsg); 9 } 10 StringBuilder groupKey = new StringBuilder(); 11 someEntityProperties.forEach(someEntityProperty -> { 12 String fieldNameByField = someEntityProperty.getName(); 13 groupKey.append(""").append(fieldNameByField).append(""").append(":").append(""").append(String.valueOf(dataMap.get(fieldNameByField))).append("""); 14 }); 15 // log.debug("依多属性字段分组,分组依据为:{}", groupKey.toString()); 16 return groupKey.toString(); 17 }