簡體   English   中英

如何使用lambda從List <>獲取總和和最小日期

[英]how to get sum and lowest date from the List<> with lambda

public class BusinessLog {

private Date logDate;
private double prize;

}

給定對象BusinessLog,我需要為List<BusinessLog> list所有獎項求和,還需要從列表中返回最低日期,是否可以使用lambda,

我可以用forEach做到這一點,但是如何用lambda做,

我到目前為止試圖做的是,

    BigDecimal balance = BigDecimal.ZERO;

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

        });
    }

要計算多個自定義聚合,您應該編寫自定義縮減器。

例如,以下reducer計算一個BusinessLog對象中的統計信息。 下面假設要聲明的構造函數public BusinessLog(double prize, Date logDate)

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作為臨時統計持有者本質上是一種黑客行為。 您需要為此目的設計一個單獨的類。

使用流媒體的解決方案

要查找最短日期,您可以執行以下操作:

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

並計算總和:

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

我不擔心“優化”這個並嘗試在一個循環中執行它,除非這可能是您系統中的主要瓶頸(不太可能)。 保持兩個想法分開使代碼更容易理解和維護。

你使用BigDecimal

用於對BigDecimal執行balance.add(...)代碼實際上不會按照您編寫它的方式工作,因為BigDecimal上的add方法返回一個新實例而不是改變現有實例。 BigDecimal實例是不可變的。 您無法為balance分配新值,因為它實際上是從lambda的上下文中final得到的。

但是使用BigDecimal的想法很好。 對於精確小數位很重要的任何事情(例如金錢),你應該避免使用double 如果您將prize更改為BigDecimal,則無法使用sum()但您可以使用reduce()來實現相同的功能。

BigDecimal sum = list.stream().map(v -> v.prize).reduce(BigDecimal.ZERO, BigDecimal::add);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM