Java 8 Java 8使用流,查找最新状态,如果';F';从相应的“发件人”状态替换原因';R';
我有一个包含字段名的对象列表,如下所示,我正在尝试替换 状态“R”对应原因字段中的状态“F”。仅当每个发布服务器的最新状态(按时间戳)的状态为“F”时,才需要执行此操作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' --
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'
我将在下面提供我的实现,如果需要任何改进,请告诉我
上面的地图会有 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));