I want to create instance of object MyObject, each field of which will be sum of values of that field from
I create an object
public class MyObject{
int value;
double length;
float temperature;
MyObject(int value, double length, float temperature){
this.value = value;
this.length = length
this.temperature = temperature
}
}
Then I construct list of objects:
List<MyObject> list = new ArrayList<MyObject>{{
add(new MyObject(1, 1d, 1.0f));
add(new MyObject(2, 2d, 2.0f));
add(new MyObject(3, 3d, 3.0f));
}}
I want create object (new MyObject(6, 6d, 6f)
)
It is easy to sum one field per stream:
Integer totalValue = myObjects.parallelStream().mapToInt(myObject -> myObject.getValue()).sum(); //returns 6;
or
Double totalLength = myObjects.parallelStream().mapToDouble(MyObject::getLength).sum(); //returns 6d
and then construct object new MyObject(totalValue, totalLength, totalTemperature);
But can I sum all fields in one stream? I want stream to return
new MyObject(6, 6d, 6.0f)
The other solutions are valid, but they both incur unnecessary overhead; one by copying MyObject
multiple times, the other by streaming the collection multiple times. If MyObject
is mutable, the ideal solution would be a mutable reduction using collect()
:
// This is used as both the accumulator and combiner,
// since MyObject is both the element type and result type
BiConsumer<MyObject, MyObject> reducer = (o1, o2) -> {
o1.setValue(o1.getValue() + o2.getValue());
o1.setLength(o1.getLength() + o2.getLength());
o1.setTemperature(o1.getTemperature() + o2.getTemperature());
}
MyObject totals = list.stream()
.collect(() -> new MyObject(0, 0d, 0f), reducer, reducer);
This solution only creates a single additional MyObject
instance, and only iterates the list once.
It is a direct application for reduce
method:
Stream.of(new MyObject(1, 1d, 1.0f), new MyObject(2, 2d, 2.0f), new MyObject(3, 3d, 3.0f)).
reduce((a, b) -> new MyObject(a.value + b.value, a.length + b.length, a.temperature + b.temperature))
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