2017-11-30 9 views
3

それぞれListのクラスにそれぞれMapがあるとします。 MapJava 8ストリーム - マップをマージして「値」の平均を計算する

public class Test { 
    public Map<Long, Integer> map; 
} 

LongキーはタイムスタンプとスコアされInteger値です。

私はユニークなタイムスタンプ(Long S)および平均スコアを持つすべてのオブジェクトのマップと出力Mapを組み合わせることができStreamを作成しようとしています。

私はこのコードを持っているが、それは私にすべてのスコアの合計とを与えない平均Integerクラスは平均法を持っていません)。

Test test1 = new Test(); 
    test1.map = new HashMap() {{ 
     put(1000L, 1); 
     put(2000L, 2); 
     put(3000L, 3); 
    }}; 

    Test test2 = new Test(); 
    test2.map = new HashMap() {{ 
     put(1000L, 10); 
     put(2000L, 20); 
     put(3000L, 30); 
    }}; 

    List<Test> tests = new ArrayList() {{ 
     add(test1); 
     add(test2); 
    }}; 

    Map<Long, Integer> merged = tests.stream() 
      .map(test -> test.map) 
      .map(Map::entrySet) 
      .flatMap(Collection::stream) 
      .collect(
        Collectors.toMap(
          Map.Entry::getKey, 
          Map.Entry::getValue, 
          Integer::sum 

        ) 
      ); 
    System.out.println(merged); 

私は、これはとてもとてもユニークなタイムスタンプと、すべてのスコアのListMapと出力も大丈夫だと思う、単一Streamに解決する簡単な問題ではないかもしれないと考えています。それで私は自分自身の平均を計算することができます。

Map<Long, List<Integer>> 

可能でしょうか?代わりにCollectors.groupingBy使用Collectors.toMap

答えて

4

Map<Long, Double> merged = tests.stream() 
     .map(test -> test.map) 
     .map(Map::entrySet) 
     .flatMap(Collection::stream) 
     .collect(
       Collectors.groupingBy(
         Map.Entry::getKey, 
         Collectors.averagingInt(Map.Entry::getValue) 
       ) 
     ); 

ああ、あなたはおそらく、もうそれを必要としないにもかかわらず、あなたが得ることができるMap<Long, List<Integer>>あなたが同じように簡単にあなたの質問の最後の部分では約尋ねました:

Map<Long, List<Integer>> merged = tests.stream() 
    .map(test -> test.map) 
    .map(Map::entrySet) 
    .flatMap(Collection::stream) 
    .collect(
      Collectors.groupingBy(
        Map.Entry::getKey, 
        Collectors.mapping(Map.Entry::getValue, Collectors.toList()) 
      ) 
    ); 
+0

大変ありがとうございました – Martin

+2

私は、いつもメソッドリファレンスを使用してみる必要はないと思います。 (Map :: entrySet).flatMap(Collection :: stream)。 '' .map(test - > test.map)よりも簡単です.map(Map :: entrySet) '.flatMap(test - > test.map.entrySet '、imho – Holger

+0

@Holger私は同意します。私はパイプラインのその部分に集中していなかったことを認めなければならず、それは問題ではなかったのでそのまま維持しました。 – Eran

関連する問題