java8流和多个

Geo*_*ler 6 java collections sum java-8 java-stream

我很好奇,如何在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();
});
Run Code Online (Sandbox Code Playgroud)

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

Łuk*_*asz 7

假设slaContractList是一个SlaContract对象列表,它有构造函数,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();
Run Code Online (Sandbox Code Playgroud)

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

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

  • `reduce`不应该在累积期间修改其输入参数.这将在并行运行时中断,它应该始终返回包含累积的新对象.[另见](http://stackoverflow.com/questions/23869930/is-the-accumulator-of-reduce-in-java-8-allowed-to-modify-its-arguments).你想在这里使用`collect`. (3认同)

Łuk*_*asz 6

尝试使用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();
Run Code Online (Sandbox Code Playgroud)

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

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