使用流api对对象列表中的多个不同字段求和?

时间:2016-10-14 09:11:53

标签: java java-8

在Java 8中,如果我有一个像这样的对象列表:

 MyObject
   double a;
   double b;
   double c;

我想获取对象列表中每个字段的总数。我能做到的一种方法如下:

double totalA = myListOfObjects.stream().map(e -> e.getA()).reduce(0.0, (x, y) -> x + y);
double totalB = myListOfObjects.stream().map(e -> e.getB()).reduce(0.0, (x, y) -> x + y);
double totalC = myListOfObjects.stream().map(e -> e.getC()).reduce(0.0, (x, y) -> x + y);  

但是有没有把它组合成一个通过使用流api的对象列表?如果我只是写了一个for / while循环(见下文)并手动累加了3个总计,那么看起来就比上面的3行代码更有效了)

for (MyObject obj: myListOfObjects) {
    totalA += obj.getA();
    totalB += obj.getB();
    totalC += obj.getC();
}

由于

1 个答案:

答案 0 :(得分:9)

您可以像这样缩小为新的MyObject个对象:

MyObject totals = myListOfObjects.stream()
    .reduce((x, y) -> new MyObject(
        x.getA() + y.getA(),
        x.getB() + y.getB(),
        x.getC() + y.getC()
    ))
    .orElse(new MyObject(0, 0, 0));

totalA = totals.getA();
totalB = totals.getB();
totalC = totals.getC();

无论如何,我认为你不应该担心这里的表现。所有三个解决方案(您的问题中的2个以及上面的我的解决方案)都有O(n)时间复杂度。我建议做一些关于过早优化的阅读。只需选择最易读且最容易理解的代码。

您还可以提取代码,将两个对象加到MyObject类:

中的方法中
public class MyObject {

    // fields, constructors, getters etc.

    public MyObject sum(MyObject other) {
        return new MyObject(
                this.a + other.a,
                this.b + other.b,
                this.c + other.c
        );
    }
}

这将允许您使用方法参考:.reduce(MyObject::sum)