2016-08-22 76 views
2

的流中的每個字段我要創建的對象的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) 

回答

2

其他解決方案是有效的,但它們都會產生不必要的開銷;一個通過複製MyObject多次,另一個通過多次流式傳輸集合。如果MyObject是可變的,理想的解決方案將是一個mutable reduction使用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); 

此解決方案僅會創建一個額外的MyObject情況下,只有遍歷列表一次。

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)) 
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來做同樣的事情。

+0

這可以避免創建中間的'MyObject'實例,與'reduce'的版本進行比較。 – frenzykryger