Java 8 GroupBy并将结果转换为列表

问题描述

你好,我必须按多个字段分组并按其中一个文件进行摘要,然后我必须处理此结果并进行更多转换。我的问题是,分组后我得到的结构很复杂,使用这个项目并不容易。这是我的代码

Map<String,Map<String,Map<LocalDateTime,Double>>>> processed = null;

processed = itemsToProcess
          .stream()
          .collect(groupingBy(entity::getId,groupingBy(entity::getType,groupingBy(entity::getCreateDate,groupingBy(entity::getCode,summingDouble(entity::getPay))))));

该分组的目的是工资的汇总,但是此后II必须对此processed结构进行一些转换,我怀疑是否有一种方法可以将其转换为简单的清单以使这个任务更容易吗?

我的输入基本上是以下列表:

List<Person> itemsToProcess= new ArrayList<>();


    @JsonInclude
    public class Person extends Entity<Person > {
    
      private static final long serialVersionUID = 1L;
    
    
      /* File line content */
      private String id;
      private String type;
      private LocalDateTime createDate;
      private String code;
      private double pay;
      private String city
      private String company
    }

我要查找的输出是按{id,type,createDate,pay}分组的pay字段的摘要

例如,如果我有一个

Id   type    createdDAte    Code   pay    more fields....
1     0         today        BC    500     
1     0         today        BC    600
2     0         today        BC    600
2     0         today        BC    300
3     0         today        BC    300

The result must be:

Id   type    createdDAte    Code   pay    more fields....
1     0         today        BC    1100
2     0         today        BC    900
3     0         today        BC    300

解决方法

您可以使用Collectors.toMap来映射这四个属性,并合并同一组人员对象并使用构造函数创建一个新对象。

List<Person> processed = 
      new ArrayList<>(
        itemsToProcess
        .stream()
        .collect(Collectors.toMap(
            i -> Arrays.asList(i.getId(),i.getType(),i.getCreateDate(),i.getCode()),i -> i,(a,b) -> new Person(a.getId(),a.getType(),a.getCreateDate(),a.getCode(),a.getPay() + b.getPay())))
        .values());

输出:

Person [id=2,type=0,createDate=2020-08-18T12:26:15.616034800,code=BC,pay=900.0]
Person [id=3,pay=300.0]
Person [id=1,pay=1100.0]

演示here

,

快速方法是按关键字段的地图进行分组:

 groupingBy(e -> Map.<String,Object>of(
    "id",e.getId(),"type",e.getType(),"createDate",e.getCreateDate(),"code",e.getCode(),"pay",e.getPay()
 ),identity())

Map的equals()方法可以像您希望的那样工作。