当前位置: 首页 > 知识库问答 >
问题:

如何使用lambda从列表中获取总和和最低日期

郭兴平
2023-03-14
public class BusinessLog {

private Date logDate;
private double prize;

}

给定对象BusinessLog,我需要为列表中的所有奖品求和

我当然可以用forEach做,但如何用lambda做,

到目前为止,我一直试图做的是,

    BigDecimal balance = BigDecimal.ZERO;

    if (list != null) {
        list.forEach(businessLog -> {
            balance.add(BigDecimal.valueOf(businessLog.getPrize()));
            // how to get lowest date 

        });
    }

共有2个答案

督弘化
2023-03-14

要计算多个自定义聚合,您应该编写一个自定义缩减器。

例如,下面的reducer计算一个BusinessLog对象中的统计信息。下面假设要声明一个构造函数publicbusinesslog(双奖,datelogdate)

BusinessLog stats = 
        bl.stream()
        .reduce((log1, log2) -> new BusinessLog(
                log1.getPrize() + log2.getPrize(),
                log1.getLogDate().before(log2.getLogDate()) ?
                     log1.getLogDate() : log2.getLogDate()
            )).get();

Date lowestDate = stats.getLogDate();
double prizeSum = stats.getPrize();

请注意,使用BusinessLog作为临时统计数据持有人本质上是一种黑客行为。为此,您需要设计一个单独的类。

史默
2023-03-14

要找到最短日期,您可以这样做:

Optional<Date> minDate = list.stream().map(v -> v.logDate).min(Date::compareTo);

并计算总和:

double sum = list.stream().mapToDouble(v -> v.prize).sum();

我不会担心“优化”这个并试图在一个循环中完成它,除非这是你系统中的一个主要瓶颈(不太可能)。将这两个想法分开使得代码更容易理解和维护。

你的代码做balance.add(...)BigDecimal实际上不会像你写的那样工作,因为BigDecimal上的add方法返回一个新的实例,而不是改变BigDecimal实例是不可变的。您不能为平衡分配新值,因为它实际上是lambda上下文中的最终

不过,使用BigDecimal是个好主意。对于精确的小数位数很重要的任何东西(如金钱),都应避免使用double。如果将prize更改为大十进制,则不能使用sum(),但可以使用reduce()来实现相同的功能。

BigDecimal sum = list.stream().map(v -> v.prize).reduce(BigDecimal.ZERO, BigDecimal::add);
 类似资料:
  • 问题内容: 我想从 handleClick 函数中给定的日期列表中获得最大日期。如何使用 moment.js 从日期列表中找到最大日期? 我有以下代码: 问题答案: 您可以使用moment.max函数:

  • 现在,我希望获得和值最小的属性,以及其他和值最大的列表。 我知道减少... 但是是否可以用最小的获得和最大的获得? 如何获得这些列表?

  • 问题内容: 我想从2个不同的表中获得几列的总和(这些表具有相同的结构)。 如果我只考虑一个表,我会写这种查询: 但是,我也想使用表T_BAR中的数据,然后使用查询返回以下列: MONTH_REF SUM(T_FOO.amount1)+ SUM(T_BAR.amount1) SUM(T_FOO.amount2)+ SUM(T_BAR.amount2) 一切都按的值分组。 请注意,给定记录可以在一个表

  • 我有这样的课: 和类似的列表,其中填充了元素。 如何使用Java8获得的最小值和最大值?

  • 我有一个特定目录中的文件名列表, 我正在尝试使用re。按如下方式搜索此内容 现在,当我打印过滤值时,它会再次打印整个文件名,我如何才能让它只打印文件名的某些部分 这里是我看到的 相反,我想 我该怎么做?

  • 初始数据: 使用此查询: 我得到: 但我需要分组“quotite”时,下一行是相同的,并显示第一行的开始日期和最后一行的日期。 预期结果: gordon提供的解决方案: 选择agenhi,tacthi,min(dtfihi)作为start_date,lead(max(dtfihi))over(按agenhi分区,seqnum-seqnum_2按max(dtfihi)排序)作为end_date,fr