java8流和多个

我很好奇,如何在java8流中总结多个变量。

Integer wCPU = 0; Double wnetwork = 0.0; Double wMem = 0.0; this.slaContractList.forEach(sla -> { wCPU += sla.getNumberOfCPUs(); wnetwork += sla.getNetworkBandwith(); wMem += sla.getMemory(); }); 

但是,这不会编译,因为lambda表达式中的变量应该是final。

假设slaContractListSlaContract对象的列表,并且它具有构造函数SlaContract(numberOfCPUs, networkBandwith, memory)您可以:

 SlaContract sumContract = slaContractList.stream() .reduce(new SlaContract(0, 0.0, 0.0), (sla1, sla2) -> { return new SlaContract(sla1.getNumberOfCPUs() + sla2.getNumberOfCPUs(), sla1.getworkBandwith() + sla2.getworkBandwith(), sla1.getMemory() + sla2.getMemory()); }); Double wnetwork = sumContract.getworkBandwith(); Double wMem = sumContract.getMemory(); Integer wCPU = sumContract.getNumberOfCPUs(); 

同样的解决方案,但对于简单的类:

 Point sumPoint = pointsList.stream() .reduce(new Point(0, 0), (p1, p2) -> { return new Point(p1.x + p2.x, p1.y + p2.y); }); 

尝试使用Stream.reduceStream.sum

 Double wnetwork = slaContractList.stream() .mapToDouble(sla -> sla.getNetworkBandwith()) .sum(); Double wMem = slaContractList.stream() .mapToDouble(sla -> sla.getMemory()) .sum(); Integer wCPU = slaContractList.stream() .mapToInt(sla -> sla.getNumberOfCPUs()) .sum(); 

请参阅https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html

使用stream的优点是可以选择使用parallelStream()而不是stream() 。 在某些情况下,它可能比简单的循环更有效。

只是做一个总和,我会像Łukasz的答案一样使用流的求和操作,但是,对于解决“最终问题”的更通用的解决方案,你可以使用java.util.concurrent.atomic的类。 它旨在用于流并且是线程安全的,因此可以在并行流中使用。

 AtomicInteger wCPU = new AtomicInteger(); DoubleAccumulator wnetwork = new DoubleAccumulator(Double::sum,0.d); DoubleAccumulator wMem = new DoubleAccumulator(Double::sum,0.d); this.slaContractList.forEach(sla -> { wCPU.addAndGet(sla.getNumberOfCPUs()); wnetwork.accumulate(sla.getNetworkBandwith()); wMem.accumulate(sla.getMemory()); }); 

现在你看到有两种实现: Accumulator和Atomic ,这两者之间的选择是另一个问题:

java 8:LongAdder和LongAccumulator是AtomicLong的首选吗?

我会这样做一个简单的黑客:

  Integer[] wCPU = new Integer[1]; Double[] wnetwork = new Double[1]; Double[] wMem = new Double[1]; this.slaContractList.forEach(sla -> { wCPU[0] += sla.getNumberOfCPUs(); wnetwork[0] += sla.getNetworkBandwith(); wMem[0] += sla.getMemory(); }); 

两者都有final关键字是可选的,因为在Java 8中他们已经引入了有效的最终概念。 这意味着,您只分配了一次。