我有一个包含项目的列表,其中每个项目都是一个对象,其中包含我感兴趣的getter方法。我想在完整列表上运行以总结所有这些getter结果。
当我使用java 8流时,它看起来像这样:
double currentProduction = itemList.stream().collect(
Collectors.summingDouble((e) -> e.getProduction(param)));
在普通的旧java中,它看起来像这样:
for (Item item : itemList) {
currentProduction += item.getProduction(param);
}
两种方法产生完全相同的结果,但我的记录器报告,对于每个项目实例,在java 8流解决方案的情况下,getProduction()方法运行TWICE。在普通的旧java列表迭代解决方案中,getProduction方法只是按预期运行一次。
由于getProduction方法成本很高,这对我来说是一个问题。
这是为什么?我能做些什么(除了只使用for循环)?
答案 0 :(得分:12)
Collectors.summingDouble
的实施存在错误。
您可以改为使用itemList.stream().mapToDouble(Class1::getProduction).sum()
。
错误详情:
Collector
实施的来源。
return new CollectorImpl<>(
() -> new double[3],
(a, t) -> { sumWithCompensation(a, **mapper.applyAsDouble(t)**);
a[2] += **mapper.applyAsDouble(t)**;},
(a, b) -> { sumWithCompensation(a, b[0]);
a[2] += b[2];
return sumWithCompensation(a, b[1]); },
a -> computeFinalSum(a),
CH_NOID);
错误由**
标记。他们两次调用mapper.applyAsDouble(t)
。
答案 1 :(得分:4)
这里有一个小MCVE来展示错误报告JDK-8151123中解决的问题,该问题在talex
的答案中提到import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SO {
static class CoffeeBabe {
final Double value;
CoffeeBabe(Double value) {
this.value = value;
}
Double getProduction() {
System.out.println("getProduction() for " + this.value);
return value;
}
}
public static void main(String[] args) {
List<CoffeeBabe> itemList = Arrays.asList(
new CoffeeBabe(13.0),
new CoffeeBabe(14.0),
new CoffeeBabe(15.0)
);
System.out.println("mapToDouble...");
double sum = itemList.stream()
.mapToDouble(CoffeeBabe::getProduction).sum();
System.out.println("sum = " + sum);
System.out.println("\nCollectors.summingDouble");
sum = itemList.stream().collect(Collectors.summingDouble(
CoffeeBabe::getProduction));
System.out.println("sum = " + sum);
}
}
输出
mapToDouble...
getProduction() for 13.0
getProduction() for 14.0
getProduction() for 15.0
sum = 42.0
Collectors.summingDouble
getProduction() for 13.0
getProduction() for 13.0
getProduction() for 14.0
getProduction() for 14.0
getProduction() for 15.0
getProduction() for 15.0
sum = 42.0