2016-06-14 8 views
4

ストリームから新しいオブジェクトに合計して平均化して変換することは可能ですか? 私は今、私は(だけでなく、コードによってコードと平均価格で合計価格)このオブジェクトリストの平均と合計を取得したいオブジェクトJava 8 Lambdas - ストリームから合計し平均する方法

public class Foo { 
     private String code; 
     private double price; 
     .... 
    } 

を持って

foos = Arrays.asList(
      new Foo("MTN" , 200), 
      new Foo("MTN" , 210), 
      new Foo("MTN" , 205), 
      new Foo("OMT" , 300), 
      new Foo("OMT" , 320), 
      new Foo("OMT" , 310), 
      new Foo("AAA" , 650), 
      new Foo("AAA" , 680), 
      new Foo("AAA" , 600)); 

私はその後、作成したいです新しいオブジェクト(foob型は

public class FooB { 
     private String code; 
     private double total; 
     private double average; 
     .... 
    } 

これは、私はそれが動作しますが、私は二回流れて行く。私は一度ストリームを通過することによってこれを行うことができます方法をしたい、今持っているものです。

Map<String, Double> averagePrices = foos.stream() 
      .collect(
        Collectors.groupingBy(
        Foo::getCode,Collectors.averagingDouble(Foo::getPrice))); 



    Map<String, Double> totalPrices = foos.stream() 
      .collect(
        Collectors.groupingBy(
          Foo::getCode, 
          Collectors.summingDouble(Foo::getPrice))); 


    List<FooB > fooBs = new ArrayList<>(); 
    averagePrices.forEach((code, averageprice)-> { 
     FooB fooB = new FooB (code , totalPrices.get(code) , averageprice); 
     fooBs.add(fooB); 
    }); 

    fooBs.forEach(e -> System.out.println(e.toString())); 

これを繰り返すことなくこれを行うより良い方法がありますか?おかげ

+1

/java/util/stream/Collector.html) 'FooB'オブジェクトを返すクラス – flakes

答えて

8

あなたはFooBにマッピングする前に、両方の結果を保持するためにDoubleSummaryStatisticsを使用することができます:カスタム[コレクタ](https://docs.oracle.com/javase/8/docs/apiを作ることができ

Map<String, DoubleSummaryStatistics> data = foos.stream() 
       .collect(Collectors.groupingBy(Foo::getCode, 
            Collectors.summarizingDouble(Foo::getPrice))); 

List<FooB> fooBs = data.entrySet().stream() 
     .map(e -> new FooB(e.getKey(), e.getValue().getSum(), e.getValue().getAverage())) 
     .collect(toList()); 
+0

チップをありがとう(DoubleSummaryStatistics) –

関連する問題