我有这样的对象
class DailyReport{
LocalDate day;
Long criticalErrors;
Long browserErrors;
Long OtherErrors;
}
现在,我获得了此对象的列表,并想创建摘要对象,即
class Summary{
LocalDate startDate;
LocalDate endDate;
Long sumOfCritical;
Long sumOfBrowser;
Long sumOfOthers
}
我这样创建了某事:
List<DailyReport> dailyReports=repository.findAll();
Summary summary = new Summary(
dailyReports.get(0).getDay;
dailyReports.get(dailyReports.size() - 1).getDay;
summary.stream().mapToLong(DailyReport::getCriticalErrors).sum(),
summary.stream().mapToLong(DailyReport::getBrowserErrors).sum(),
summary.stream().mapToLong(DailyReport::getOtherErrors).sum(),
}
但是对我来说,它看起来效率低下-有更好的方法吗?
答案 0 :(得分:2)
您可以通过实现将报告“添加”到摘要对象的逻辑以及组合两个摘要对象的逻辑来减少数据流。
这是下面的样子:
//Adds a report to a summary
BiFunction<Summary, DailyReport, Summary> reportMerger = (summ, rep1) -> {
Summary summary = new Summary();
summary.setStartDate(rep1.getDay().isAfter(summ.getStartDate()) ?
rep1.getDay() : summ.getStartDate());
summary.setEndDate(rep1.getDay().isAfter(summ.getEndDate()) ?
summ.getEndDate() : rep1.getDay());
summary.setSumOfCritical(rep1.getCriticalErrors()
+ summ.getSumOfCritical());
summary.setSumOfBrowser(rep1.getBrowserErrors()
+ summ.getSumOfBrowser());
summary.setSumOfOthers(rep1.getOtherErrors()
+ summ.getSumOfOthers());
return summary;
};
//combines 2 summary objects
BinaryOperator<Summary> summaryMerger = (s1, s2) -> {
Summary summ = new Summary();
summ.setStartDate(s1.getStartDate().isBefore(s2.getStartDate()) ?
s1.getStartDate() : s2.getStartDate());
summ.setEndDate(s1.getEndDate().isBefore(s2.getEndDate()) ?
s2.getEndDate() : s1.getEndDate());
summ.setSumOfCritical(s1.getSumOfCritical()
+ s2.getSumOfCritical());
summ.setSumOfBrowser(s1.getSumOfBrowser()
+ s2.getSumOfBrowser());
summ.setSumOfOthers(s1.getSumOfOthers()
+ s2.getSumOfOthers());
return summ;
};
然后将报告流简化为一个摘要
Summary summary = dailyReports.stream()
.reduce(new Summary(), reportMerger, summaryMerger);
注意:您需要在上述比较中为new Summary()
的空字段添加空检查(以避免NPE)。
另一种收集方法(感谢Eugene的评论)消除了对新对象的需求:
Summary summaryTwo = dailyReports.stream().collect(Collector.of(Summary::new,
(summ, rep) -> {
//add rep to summ
}, (summary1, summary2) -> {
//merge summary2 into summary1
return summary1;
}));
答案 1 :(得分:1)
您可以循环使用DailyReports并计算类似值
LocalDate startDate = dailyReports.get(0).getDay;
LocalDate endDate = dailyReports.get(dailyReports.size() - 1).getDay;
Long sumOfCritical=0L;
Long sumOfBrowser=0L;
Long sumOfOthers=0L;
dailyReports.stream().foreach(o->{
sumOfCritical += o.getCriticalErrors();
sumOfBrowser += o.getBrowserErrors();
sumOfOthers += o.getOtherErrors();
})
Summary summary = new Summary(startDate, endDate,sumOfCritical, sumOfBrowser, sumOfOthers)
如果您需要更多详细信息,可以转到know about stream api或know about lambda expression