Java 8 Java 8使用流,查找最新状态,如果';F';从相应的“发件人”状态替换原因';R';

Java 8 Java 8使用流,查找最新状态,如果';F';从相应的“发件人”状态替换原因';R';,java-8,hashmap,java-stream,grouping,Java 8,Hashmap,Java Stream,Grouping,我有一个包含字段名的对象列表,如下所示,我正在尝试替换 状态“R”对应原因字段中的状态“F”。仅当每个发布服务器的最新状态(按时间戳)的状态为“F”时,才需要执行此操作 auditedBy status time Reason api-a S 10:20 'A1' api-a R 10:25 'A2' api-a F 10:30 'A3' --

我有一个包含字段名的对象列表,如下所示,我正在尝试替换 状态“R”对应原因字段中的状态“F”。仅当每个发布服务器的最新状态(按时间戳)的状态为“F”时,才需要执行此操作

auditedBy   status    time        Reason 
api-a         S        10:20       'A1'
api-a         R        10:25       'A2'
api-a         F        10:30       'A3' 
-----
api-b         S        10:30       'B1'
api-b         S        10:25       'B2'
api-b         S        10:20       'B3'
-----
api-c         S        10:20       'C1' 
api-c         S        10:30       'C1'
api-c         F        10:40       'C3'
因此,上述数据的最终输出将为

auditedBy   status    time        Reason 
api-a         S        10:20       'A1'
api-a         R        10:25       'A2'
api-a         F        10:30       'A2' ******

api-b         S        10:30       'B1'
api-b         S        10:25       'B2'
api-b         S        10:20       'B3'

api-c         S        10:20       'C1' 
api-c         S        10:30       'C1'
api-c         F        10:40       'C3'
我将在下面提供我的实现,如果需要任何改进,请告诉我

  • 我将创建最新状态为“F”的地图 地图会有

    api-a->api-a,F,10:30,'A3' api-c->api-c,F,10:40,'C3'

  • 然后我将创建映射,它将包含记录 前一个映射中的记录状态为“R”。
    上面的地图会有

    api-a->api-a,R,10:25,'A2'

  • 我将从两个地图的原始列表中更改原因

  • private List changereason函数(列表记录){
    映射事件失败=记录。流()
    .collect(toMap(DetailRecord::getAuditedBy,Function.identity(),
    maxBy(Comparator.comparing(DetailRecord::getAuditTimestamp)))
    .values()
    .stream().filter(detRec->FAILED.getStatus().equals(detRec.getStatus()))
    .collect(toMap(DetailRecord::getAuditedBy,Function.identity());
    Map retryRecordForFailedEvents=记录。流()
    .filter(rec->eventsFailed.keySet().contains(rec.getAuditedBy()))
    .filter(rec->FAILED_RECOVERABLE_ERROR.getStatus().equals(rec.getStatus()))
    .collect(toMap(DetailRecord::getAuditedBy,Function.identity(),
    maxBy(Comparator.comparing(DetailRecord::getAuditTimestamp));
    记录。forEach(记录->{
    if(events失败.containsKey(rec.getAuditedBy())&&
    eventsFailed.get(rec.getAuditedBy()).getAuditTimestamp()
    .compareTo(rec.getAuditTimestamp())==0){
    DetailRecord obj=retryRecordForFailedEvents.get(rec.getAuditedBy());
    如果(obj!=null){
    rec.setExceptionReason(obj.getExceptionReason());
    rec.setExceptionDetail(obj.getExceptionDetail());
    }
    }
    });
    退货记录;
    }
    
    您可以使用
    groupingBy
    收集器进行如下尝试:

    private List<DetailRecord> changeReasonFunction(List<DetailRecord> records) {
        return records.stream()
                .collect(Collectors.groupingBy(DetailRecord::getAuditedBy))
                .values().stream()
                .flatMap(list -> {
                    Optional<DetailRecord> maxRecord = list.stream().max(Comparator.comparing(DetailRecord::getTime));
                    if (maxRecord.isPresent()
                            && maxRecord.get().getStatus().equals("F")
                            && list.stream().anyMatch(detailRecord -> detailRecord.getStatus().equals("R"))) {
                        maxRecord.get().setReason(
                                list.stream()
                                        .filter(detailRecord -> detailRecord.getStatus().equals("R"))
                                        .findAny().get().getReason());
                    }
                    return list.stream();
                }).collect(Collectors.toList());
    }
    
    测试:

    listl=newarraylist();
    l、 添加(新的详细记录(“api-a”、“S”、即时解析(“2019-01-01T10:20:00.00Z”)、“A1”);
    l、 添加(新的详细记录(“api-a”、“R”、即时解析(“2019-01-01T10:25:00.00Z”)、“A2”);
    l、 添加(新的详细记录(“api-a”、“F”、即时解析(“2019-01-01T10:30:00.00Z”)、“A3”);
    l、 添加(新的详细记录(“api-b”、“S”、即时解析(“2019-01-01T10:30:00.00Z”)、“B1”);
    l、 添加(新的详细记录(“api-b”、“S”、即时解析(“2019-01-01T10:25:00.00Z”)、“B2”);
    l、 添加(新的详细记录(“api-b”、“S”、即时解析(“2019-01-01T10:20:00.00Z”)、“B3”);
    l、 添加(新的详细记录(“api-c”、“S”、即时解析(“2019-01-01T10:20:00.00Z”)、“C1”);
    l、 添加(新的详细记录(“api-c”、“S”、即时解析(“2019-01-01T10:30:00.00Z”)、“C1”);
    l、 添加(新的详细记录(“api-c”、“F”、即时解析(“2019-01-01T10:40:00.00Z”)、“C3”);
    System.out.println(changeReasonFunction(l));
    

    输出与您预期的一样。

    我使用与中相同的
    DetailRecord

    开始时,我们根据
    auditedBy

    Map groupByCollection=inputList.stream()
    .collect(收集器.groupingBy(DetailRecord::getAuditedBy));
    
    现在我们可以在每一张单子上做替换。列表已排序,在reduce方法中搜索状态为“R”的第一条记录。如果找到,则保留该记录,并继续搜索状态为“F”的记录,如果找到,则进行替换

    groupByCollection.entrySet().forEach(e->e.getValue().stream())
    .sorted(Comparator.comparing(DetailRecord::getTime))
    .reduce(空,(详细记录a,详细记录v)->{
    如果(a==null&&v.getStatus().equals(“R”)){
    返回v;
    }
    如果(a!=null&&v.getStatus().equals(“F”)){
    v、 setReason(a.getReason());
    }
    返回a;
    },(a1,a2)->a1)
    );
    groupByCollection.entrySet()
    .forEach(e->e.getValue().stream().forEach(System.out::println));
    
    初始化列表代码示例:

    List inputStrings=Arrays.asList(
    “api-a S 10:20‘A1’”,
    “api-a R 10:25‘A2’”,
    “api-a F 10:30‘A3’”,
    “api-b S 10:30‘B1’”,
    “api-b S 10:25‘B2’”,
    “api-b S 10:20‘B3’”,
    “api-c S 10:20‘C1’”,
    “api-c S 10:30‘C1’”,
    “api-c F 10:40‘C3’”
    );
    List inputList=inputStrings.stream()
    .map(s->s.split(\\s+))
    .map(s->new DetailRecord(s[0],s[1],Instant.parse(“2019-01-01T”+s[2]+“:00.00Z”),s[3]。replaceAll(“,”))
    .collect(Collectors.toList());
    
    谢谢@kartik我花了一段时间才理解你的解决方案,我用我的代码在本地运行,效果很好。我从
    list.stream().anyMatch(detailRecord->detailRecord.getStatus().equals(“R”){maxRecord.get().setReason
    list.stream().filter(detailRecord->detailRecord.getStatus().equals(“R”).max(比较(detailRecord::getTime))
    对于最新的问题,可能有多个状态为“R”的问题我忘记添加到我的问题中。@krrish0690抱歉,我应该解释更多。如果有任何不清楚的地方,请告诉我,我会编辑我的答案。
    public class DetailRecord {
    
        private String auditedBy;
        private String status;
        private Instant time;
        private String reason;
    }
    
    List<DetailRecord> l = new ArrayList<>();
    
    l.add(new DetailRecord("api-a", "S", Instant.parse("2019-01-01T10:20:00.00Z"), "A1"));
    l.add(new DetailRecord("api-a", "R", Instant.parse("2019-01-01T10:25:00.00Z"), "A2"));
    l.add(new DetailRecord("api-a", "F", Instant.parse("2019-01-01T10:30:00.00Z"), "A3"));
    
    l.add(new DetailRecord("api-b", "S", Instant.parse("2019-01-01T10:30:00.00Z"), "B1"));
    l.add(new DetailRecord("api-b", "S", Instant.parse("2019-01-01T10:25:00.00Z"), "B2"));
    l.add(new DetailRecord("api-b", "S", Instant.parse("2019-01-01T10:20:00.00Z"), "B3"));
    
    l.add(new DetailRecord("api-c", "S", Instant.parse("2019-01-01T10:20:00.00Z"), "C1"));
    l.add(new DetailRecord("api-c", "S", Instant.parse("2019-01-01T10:30:00.00Z"), "C1"));
    l.add(new DetailRecord("api-c", "F", Instant.parse("2019-01-01T10:40:00.00Z"), "C3"));
    
    System.out.println(changeReasonFunction(l));