我想对以下示例进行聚合:

我有一个 List<CsvEntity> toSort = 实体,如下所述:

toSort.add(new CsvEntity(...))..

public class CsvEntity {
    String OCCURRENCES, STATUS, MESSAGE, STACK_TRACE;
}

数据:
  OCCURRENCES,   STATUS,MESSAGE,STACK_TRACE
    1,       FAIL, MESSAGE1, STACK1
    1,       PASS, MESSAGE1, STACK1
    1,       FAIL, MESSAGE1, STACK1
    1,       FAIL, MESSAGE2, STACK2 => aggregate MESSAGE & STACK_TRACE)
    1,       PASS, MESSAGE2, STACK2
    1,       PASS, MESSAGE3, STACK3
    1,       PASS, MESSAGE3, STACK3

结果应该是(作为数据结构):
OCCURRENCES,STATUS,MESSAGE,STACK_TRACE
3, FAIL, MESSAGE1, STACK1
2, FAIL, MESSAGE2, STACK2
2, PASS, MESSAGE3, STACK3

我尝试使用:
Map<String, Integer> group = toSort.stream().collect(
    Collectors.groupingBy(
        CsvEntity::getSTACK_TRACE,
        Collectors.groupingBy(CsvEntity::getMESSAGE),
        Collectors.summingInt(s -> Integer.parseInt(s.getOCCURRENCES()))
    )
);

但是这个组只返回 STACK_TRACE 而不是整个 CsvEntity ...

是否有可能以及在代码中更改什么?

最佳答案

除了我的其他答案之外,您还可以使用 groupingBy 收集器,但首先我会在 equals 类中覆盖 hashcode/CsvEntity ,如下所示:

class CsvEntity {
     private String OCCURRENCES,STATUS,MESSAGE,STACK_TRACE;

     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         CsvEntity csvEntity = (CsvEntity) o;
         return Objects.equals(MESSAGE, csvEntity.MESSAGE) &&
                 Objects.equals(STACK_TRACE, csvEntity.STACK_TRACE);
     }

     @Override
     public int hashCode() {
         return Objects.hash(MESSAGE, STACK_TRACE);
     }

     public CsvEntity(String OCCURRENCES, String STATUS,
                  String MESSAGE, String STACK_TRACE) { ... }
     ...
     ...
     ...
}

然后是流管道:
 List<CsvEntity> resultSet
                = source.stream()
                .collect(Collectors.groupingBy(Function.identity(),
                        LinkedHashMap::new,
                        Collectors.summingInt(e -> Integer.parseInt(e.getOCCURRENCES()))))
                .entrySet()
                .stream()
                .map(x -> {
                    CsvEntity c = x.getKey();
                    return new CsvEntity(Integer.toString(x.getValue()),
                          c.getSTATUS(), c.getMESSAGE(), c.getSTACK_TRACE());
                }).collect(Collectors.toList());

这再次产生以下结果:
[CsvEntity{OCCURRENCES='3', STATUS='FAIL', MESSAGE='MESSAGE1', STACK_TRACE='STACK1'},
 CsvEntity{OCCURRENCES='2', STATUS='FAIL', MESSAGE='MESSAGE2', STACK_TRACE='STACK2'},
 CsvEntity{OCCURRENCES='2', STATUS='PASS', MESSAGE='MESSAGE3', STACK_TRACE='STACK3'}]

10-06 05:17