我有以下代码,我试图改进:
BigDecimal total = entity.getAssociate().stream().map(Associates::getPropertyA)
.reduce(BigDecimal.ZERO, BigDecimal::add);
total = entity.getAssociate().stream().map(Associates::getPropertyB)
.reduce(total, BigDecimal::add);
total = entity.getAssociate().stream().map(Associates::getPropertyC)
.reduce(total, BigDecimal::add);
total = entity.getAssociate().stream().map(Associates::getPropertyD)
.reduce(total, BigDecimal::add);
它有效,但真的感觉有更好的方法。有人可以就此事启发我吗?
答案 0 :(得分:59)
如果所有这些属性属于同一类型(似乎它们都是BigDecimal
),您可以使用flatMap
创建所有属性Stream
,然后{{1它总和:
reduce
答案 1 :(得分:32)
您可以直接在地图中添加所有属性:
BigDecimal total = entity.getAssociate().stream()
.map(a -> a.getPropertyA()
.add(a.getPropertyB())
.add(a.getPropertyC())
.add(a.getPropertyD()))
.reduce(BigDecimal.ZERO, BigDecimal::add);
请注意,这会改变添加数字的顺序。
答案 2 :(得分:23)
如果您可以将以下方法添加到Associates
类:
public BigDecimal getSubtotal() {
return propertyA.add(propertyB).add(propertyC).add(propertyD);
}
然后,完成任务很容易:
BigDecimal total = entity.getAssociate().stream()
.map(Associate::getSubtotal)
.reduce(BigDecimal::add)
.orElse(BigDecimal.ZERO);
答案 3 :(得分:16)
“更好”或“最佳”这两个词应该指某个指标。性能?可读性?优雅?
answer by Eran显示了一种方法,即为每个关联创建包含属性值A,B,C和D的小流,并将这些值平面映射到更大的流中。这种方法的求和顺序是
A0 + B0 + C0 + D0 + A1 + B1 + C1 + D1 + ... + An + Bn + Cn + Dn
另一种选择是创建属性A,B,C和D的各个流,并在应用缩减之前连接这些流。这可以通过嵌套的Stream#concat
调用完成,但使用带有标识函数的flatMap
更优雅灵活:
Stream<BigDecimal> stream = Stream.of(
entity.getAssociate().stream().map(Associates::getPropertyA),
entity.getAssociate().stream().map(Associates::getPropertyB),
entity.getAssociate().stream().map(Associates::getPropertyA),
entity.getAssociate().stream().map(Associates::getPropertyC))
.flatMap(Function.identity());
BigDecimal total = stream.reduce(BigDecimal.ZERO, BigDecimal::add);
关键是在这种情况下,求和顺序是
A0 + A1 + ... + An + B0 + B1 + ... + Bn + C0 + C1 + ... + Cn
(技术上可能不会产生很大的差异。但是这是一种概念概念与目前已提出的方法(就总和顺序而言)不同的方法,因此,可能值得一提的是一个选项 - 另外,它更类似于您当前使用的方法,但没有用于减少的破坏的标识值)
答案 4 :(得分:6)
或只是forEach
:
BigDecimal[] total = new BigDecimal[] { BigDecimal.ZERO };
entity.getAssociate().stream().forEach(a -> {
total[0] = total[0].add(a.getPropertyA());
// ... and so on for all others
});
作为一个方面 - 由于您违反了identity
减少量,因此当前的实施不是错误的。