我想创建对象MyObject的实例,其中每个字段都是该字段值的总和
我创建了一个对象
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
}
}
然后我构建对象列表:
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));
}}
我想要创建对象(new MyObject(6, 6d, 6f)
)
每个流总结一个字段很容易:
Integer totalValue = myObjects.parallelStream().mapToInt(myObject -> myObject.getValue()).sum(); //returns 6;
或
Double totalLength = myObjects.parallelStream().mapToDouble(MyObject::getLength).sum(); //returns 6d
然后构造对象new MyObject(totalValue, totalLength, totalTemperature);
但是我可以在一个流中汇总所有字段吗? 我想要流回来
new MyObject(6, 6d, 6.0f)
答案 0 :(得分:3)
您可以尝试以下内容
MyObject me = new MyObject(
list.stream().mapToInt(MyObject::getValue).sum(),
list.stream().mapToDouble(MyObject::getLength).sum(),
(float)list.stream().mapToDouble(MyObject::getTemperature).sum());
这将满足您的需求。您也可以使用Stream.reduce来做同样的事情。
答案 1 :(得分:2)
其他解决方案是有效的,但它们都会产生不必要的开销;一个通过多次复制MyObject
,另一个通过多次流式传输集合。如果MyObject
是可变的,那么使用collect()
的理想解决方案是mutable reduction:
// 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);
此解决方案仅创建一个额外的MyObject
实例,并且只迭代列表一次。
答案 2 :(得分:1)
它是reduce
方法的直接应用程序:
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))