Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用特定条件创建聚合java8_Java_Java 8 - Fatal编程技术网

如何使用特定条件创建聚合java8

如何使用特定条件创建聚合java8,java,java-8,Java,Java 8,我想对以下示例进行聚合: 我有一个实体列表,如下所述: toSort.add(new CsvEntity(...)).. public class CsvEntity { String OCCURRENCES, STATUS, MESSAGE, STACK_TRACE; } 数据: OCCURRENCES, STATUS,MESSAGE,STACK_TRACE 1, FAIL, MESSAGE1, STACK1 1, PASS,

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

我有一个
实体列表,如下所述:

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
结果应为(作为数据结构):

我尝试使用:

Map<String, Integer> group = toSort.stream().collect(
    Collectors.groupingBy(
        CsvEntity::getSTACK_TRACE, 
        Collectors.groupingBy(CsvEntity::getMESSAGE),
        Collectors.summingInt(s -> Integer.parseInt(s.getOCCURRENCES()))
    )
);
Map group=toSort.stream().collect(
收集者分组(
CSventy::getSTACK_跟踪,
Collectors.groupingBy(csventy::getMESSAGE),
Collectors.summingit(s->Integer.parseInt(s.getoccurrencess())
)
);
但是这个组只返回堆栈跟踪,而不是整个CSV


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

下面是如何分组和聚合数据的示例。希望这有帮助

代码


以下是如何实现上述结果的示例:

这使用了@Boris爬行器的想法,将
消息
堆栈跟踪
属性连接为“分组依据”的值。尽管如此,在这种特定情况下,与其使用
groupingBy
收集器,不如使用
toMap
收集器

List<CsvEntity> result = new ArrayList<>(source.stream()
        .collect(Collectors.toMap(c -> c.getMESSAGE() + c.getSTACK_TRACE(),
                 v -> new CsvEntity(v.getOCCURRENCES(), v.getSTATUS(), v.getMESSAGE(), v.getSTACK_TRACE()),
                 (left, right) -> {
                     left.setOCCURRENCES(Integer.toString(Integer.parseInt(left.getOCCURRENCES())
                             + Integer.parseInt(right.getOCCURRENCES())));
                     return left;
                 }, LinkedHashMap::new))
        .values());

除了我的另一个答案之外,您可以使用
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());

csventy
的成员应该是常量吗?如果没有,请不要用大写字母来命名。当然也有可能。1) 定义正确的分组运算符-您似乎希望按消息和堆栈分组-以便将它们连接在一起进行分组。2) 定义一个适当的下游采集器,它存储消息和堆栈,并有一个计数器,您可以递增计数器,并假定对状态进行逻辑and运算。请您举个例子:)另外,正如@lutzh所说的,使用Java命名约定。变量在camelCase中。为什么
public class CsvEntity
而不是
public enum CsvEntity
?Hi@VitalyT。。我误解了这个问题。我已将代码更新为
stackTrace
Do上的唯一组,我需要通过这些属性实现hashcode/equals吗?公共布尔等于(对象o){if(this==o)返回true;if(o==null | | | getClass()!=o.getClass())返回false;CsvEntity CsvEntity=(CsvEntity)o;返回Objects.equals(getMESSAGE(),CsvEntity.getMESSAGE())和&Objects.equals(getSTACK_TRACE(),CsvEntity.getSTACK_TRACE());}@Override public int hashCode(){return Objects.hash(getMESSAGE(),getSTACK_TRACE());}@VitalyT如果您愿意,您可以,但使用当前的解决方案则不需要。在当前的解决方案中,如果两个对象具有相同的
message
stacktrace
,则它们是相等的,因此
c.getMESSAGE()+c.getSTACK_TRACE()
。哇,这样一个优雅的解决方案,很快就会检查出来:),谢谢
List<CsvEntity> result = new ArrayList<>(source.stream()
        .collect(Collectors.toMap(c -> c.getMESSAGE() + c.getSTACK_TRACE(),
                 v -> new CsvEntity(v.getOCCURRENCES(), v.getSTATUS(), v.getMESSAGE(), v.getSTACK_TRACE()),
                 (left, right) -> {
                     left.setOCCURRENCES(Integer.toString(Integer.parseInt(left.getOCCURRENCES())
                             + Integer.parseInt(right.getOCCURRENCES())));
                     return left;
                 }, LinkedHashMap::new))
        .values());
[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'}]
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'}]