使用lambda表达式的一个对象中的Java字段总和

使用lambda表达式的一个对象中的Java字段总和,java,lambda,java-8,Java,Lambda,Java 8,我有这样的物体: class DailyReport{ LocalDate day; Long criticalErrors; Long browserErrors; Long OtherErrors; } List<DailyReport> dailyReports=repository.findAll(); Summary summary = new Summary( dailyReports.get(0).getDay; dailyReports.get(dailyRep

我有这样的物体:

class DailyReport{
LocalDate day;
Long criticalErrors;
Long browserErrors;
Long OtherErrors;
}
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(),
}
现在我得到了这个对象的列表,并想创建summaryobject,即

class Summary{
  LocalDate startDate;
LocalDate endDate;
Long sumOfCritical;
Long sumOfBrowser;
Long sumOfOthers
}
我创造了这样的东西:

class DailyReport{
LocalDate day;
Long criticalErrors;
Long browserErrors;
Long OtherErrors;
}
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(),
}
List dailreports=repository.findAll();
摘要=新摘要(
DailReports.get(0.getDay);
get(dailyReports.size()-1).getDay;
summary.stream().mapToLong(DailyReport::getCriticalErrors).sum(),
summary.stream().mapToLong(DailyReport::getBrowserErrors).sum(),
summary.stream().mapToLong(DailyReport::getOtherErrors).sum(),
}

但对我来说,它看起来效率很低-有没有更好的方法来做到这一点?

您可以循环DailReports并计算如下值

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)

您可以循环DailReports并计算如下值

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)

您可以通过实现将报表“添加”到摘要对象的逻辑以及合并两个摘要对象的逻辑来减少流

下面是它的样子:

//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;
};
注意:您需要在上面的比较中为
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;
    }));

您可以通过实现将报表“添加”到摘要对象的逻辑以及合并两个摘要对象的逻辑来减少流

下面是它的样子:

//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;
};
注意:您需要在上面的比较中为
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;
    }));


为什么要使用Long,而不是Long?什么对你来说效率很低(除了不必要的装箱/拆箱操作)?请修复源代码示例。特别是最后一部分混淆了;和使用(…但随后以}结束)。说真的:不要把甚至没有编译的东西扔给我们!我想你说的是3个和“低效”。你检查了吗?
它看起来低效
=>我想没有。但它看起来可读性很好,这很好。为什么使用Long,not Long?你觉得什么低效(除了不必要的装箱/拆箱操作)?请修复源代码示例。特别是最后一部分混淆了;和使用(…但最后以}结束。说真的:不要把连编译都没有的东西扔到我们身上!我想你说“低效”的时候是在谈论3个总和".你检查过了吗?
它看起来效率不高
=>我想不是。但是它看起来可读性很好,这很好。我想你可以通过
收集器对易变的缩减做同样的事情。几乎可以通过
@Eugene的
收集器…除了
开始日期
结束日期
部分,当使用
BiConsumer
时,这部分没有位置像您这样的oks是像可变缩减一样编码的,但是使用
reduce
,在
reduce
的每个步骤中,您必须返回一个新的instance@Eugene100%。编辑了上一个函数,现在您可以开始我的第一点,如果您使用
Collector.of
,您可以做同样的事情,而不需要额外的对象,对吗?我想您也可以做同样的事情通过
Collector.of
@Eugene几乎实现可变缩减…除了
startDate
endDate
部分之外,在使用
BiConsumer
时,这两个部分没有位置。看起来,您的编码就像是可变缩减,但使用
reduce
,在
reduce
的每个步骤中,您必须返回一个新的instance@Eugene100%。编辑了上一个函数,现在您可以进入我的第一点,如果您使用
Collector.of
,您也可以做同样的事情,而不需要额外的对象,对吗?