In Java 8, if I have a list of Objects like this:
MyObject
double a;
double b;
double c;
I want to get the totals of each of these fields in the list of objects. One way I can to do it, is as follows:
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);
But is there away to combine this into one pass through the list of objects usng the streams api? If I just wrote a for/while loop (see below) and manually added up the 3 totals, that would seem more efficent then the above 3 lines of code)
for (MyObject obj: myListOfObjects) {
totalA += obj.getA();
totalB += obj.getB();
totalC += obj.getC();
}
Thanks
You can reduce into new MyObject
objects like this:
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();
Anyway, I don't think you should worry about performance here. All three solutions (2 in your question + mine above) have O(n)
time complexity. I would recommend doing some reading about premature optimisations. Just go for the code which is most readable and the easiest to understand.
You could also extract the code to sum two objects into a method in MyObject
class:
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
);
}
}
This would allow you to use a method reference: .reduce(MyObject::sum)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With