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

Java 8 Java8GroupBy并将结果转换为列表,java-8,grouping,transformation,Java 8,Grouping,Transformation,您好,我必须按多个字段分组,并按其中一个文件进行汇总,然后我必须处理此结果并进行更多转换。我的问题是,分组后我得到了一个复杂的结构,处理此项并不容易。这是我的代码: Map<String, Map<String, Map<LocalDateTime, Map<String, Double>>>> processed = null; processed = itemsToProcess .stream() .

您好,我必须按多个字段分组,并按其中一个文件进行汇总,然后我必须处理此结果并进行更多转换。我的问题是,分组后我得到了一个复杂的结构,处理此项并不容易。这是我的代码:

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

processed = itemsToProcess
          .stream()
          .collect(groupingBy(entity::getId,
              groupingBy(entity::getType,
                  groupingBy(entity::getCreateDate,
                      groupingBy(entity::getCode,
                          summingDouble(entity::getPay))))));
我要查找的输出是按{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

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

 groupingBy(e -> Map.<String, Object>of(
    "id", e.getId(),
    "type", e.getType(),
    "createDate", e.getCreateDate(),
    "code", e.getCode(),
    "pay", e.getPay()
 ), identity())
groupingBy(e->Map.of)(
“id”,即getId(),
“类型”,例如getType(),
“createDate”,例如getCreateDate(),
“代码”,例如getCode(),
“支付”,即getPay()
),identity())

Map的
equals()
方法的工作方式与您希望的一样。

您可以使用
收集器.toMap
按这四个属性进行映射,合并相同的组person对象,并使用构造函数创建一个新对象

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

演示

您真的需要所有分组依据还是只需要Id?不,必须按所有字段(Id、类型、createDate、代码)进行摸索,最后按付款进行求和。您了解它的嵌套分组而不是分组依据(Id、类型、createDate、代码)吗?你能用一个例子来说明你的输入和预期输出吗?不,对不起,这是我第一次使用这个功能。我添加了一个我想要的例子,谢谢!无法使用此方法访问getId()和其他属性您的意思是什么
map.get(“id”)
返回它只是因为我无法通过这种方式访问类的属性。您检查了代码吗?如果你面临任何问题,请随时询问。是的,它似乎工作得很完美。我唯一的疑问是,是否有一种更易于维护、更清晰的方法来实现这一点,非常感谢!
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, type=0, createDate=2020-08-18T12:26:15.616034800, code=BC, pay=300.0]
Person [id=1, type=0, createDate=2020-08-18T12:26:15.616034800, code=BC, pay=1100.0]