将多个 BigDecimals 求和到一个 Map<String, BigDecimal>
Sum multiple BigDecimals to a Map<String, BigDecimal>
我正在尝试对 List
中的多个 BigDecimals 求和。目前,我正在使用两个流,但如果可能的话,我希望只有一个流。我不确定如何以高效的方式重写下面的内容。
BigDecimal totalCharges = tableRowDataList.stream()
.map(el -> el.getSums().getCharges())
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalFees = tableRowDataList.stream()
.map(el -> el.getSums().getFees())
.reduce(BigDecimal.ZERO, BigDecimal::add);
如您所见,流的作用基本相同,只是对 getCharges/getFees 的调用不同。
从上面获得结果 Map<String, BigDecimal>
的最佳方法是什么? (关键是 charges/fees)
首先创建一个 class 用于收集结果。
然后你做与 BigDecimal 相同的事情,即一个 ZERO
常量和一个 add()
方法。
public class ChargesAndFees {
private static final ZERO = new ChargesAndFees(BigDecimal.ZERO, BigDecimal.ZERO);
private final BigDecimal charges;
private final BigDecimal fees;
// constructor and getters
public ChargesAndFees add(ChargesAndFees that) {
return new ChargesAndFees(this.charges.add(that.charges),
this.fees.add(that.fees));
}
}
现在你可以做流逻辑了
ChargesAndFees totals = tableRowDataList.stream()
.map(el -> new ChargesAndFees(el.getSums().getCharges(),
el.getSums().getFees()))
.reduce(ChargesAndFees.ZERO, ChargesAndFees::add);
如果你坚持,你可以将 totals
中的值转换为 Map
。
如果您有一个对象列表 List,其中每个对象都有一个 Sums 对象——您是否控制 TableRowDataElement and/or Sums 的定义?
如果您在 TableRowDataElement 或 Sums 中创建一个 add 方法,那么您可以简化它而无需额外的 class--
Sums sums = tableRowDataList.stream()
.map(el -> el.getSums())
.reduce(new Sums(0,0), Sums::add);
尝试 StreamEx:
Optional<Entry<BigDecimal, BigDecimal>> res = StreamEx.of(tableRowDataList)
.map(e -> e.getSums())
.mapToEntry(s -> s.getCharges(), s -> s.getFees())
.reduce((a, b) -> {
a.getKey().add(b.getKey());
b.getKey().add(b.getValue());
return a;
});
我认为我们应该尽量避免创建那些小助手类。否则,您将 运行 陷入维护 tens/hundreds 微小 类 的麻烦中。
我正在尝试对 List
中的多个 BigDecimals 求和。目前,我正在使用两个流,但如果可能的话,我希望只有一个流。我不确定如何以高效的方式重写下面的内容。
BigDecimal totalCharges = tableRowDataList.stream()
.map(el -> el.getSums().getCharges())
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalFees = tableRowDataList.stream()
.map(el -> el.getSums().getFees())
.reduce(BigDecimal.ZERO, BigDecimal::add);
如您所见,流的作用基本相同,只是对 getCharges/getFees 的调用不同。
从上面获得结果 Map<String, BigDecimal>
的最佳方法是什么? (关键是 charges/fees)
首先创建一个 class 用于收集结果。
然后你做与 BigDecimal 相同的事情,即一个 ZERO
常量和一个 add()
方法。
public class ChargesAndFees {
private static final ZERO = new ChargesAndFees(BigDecimal.ZERO, BigDecimal.ZERO);
private final BigDecimal charges;
private final BigDecimal fees;
// constructor and getters
public ChargesAndFees add(ChargesAndFees that) {
return new ChargesAndFees(this.charges.add(that.charges),
this.fees.add(that.fees));
}
}
现在你可以做流逻辑了
ChargesAndFees totals = tableRowDataList.stream()
.map(el -> new ChargesAndFees(el.getSums().getCharges(),
el.getSums().getFees()))
.reduce(ChargesAndFees.ZERO, ChargesAndFees::add);
如果你坚持,你可以将 totals
中的值转换为 Map
。
如果您有一个对象列表 List
如果您在 TableRowDataElement 或 Sums 中创建一个 add 方法,那么您可以简化它而无需额外的 class--
Sums sums = tableRowDataList.stream()
.map(el -> el.getSums())
.reduce(new Sums(0,0), Sums::add);
尝试 StreamEx:
Optional<Entry<BigDecimal, BigDecimal>> res = StreamEx.of(tableRowDataList)
.map(e -> e.getSums())
.mapToEntry(s -> s.getCharges(), s -> s.getFees())
.reduce((a, b) -> {
a.getKey().add(b.getKey());
b.getKey().add(b.getValue());
return a;
});
我认为我们应该尽量避免创建那些小助手类。否则,您将 运行 陷入维护 tens/hundreds 微小 类 的麻烦中。