15

Java Streams を使用して取得したいMap<A, Map<B, C>>と考えています。Map<B, List<C>>

私は次のようにそれをしようとします:

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) {
    return input.values()
            .stream()
            .flatMap(it -> it.entrySet().stream())
            .collect(Collectors.groupingBy(Map.Entry::getKey));
}

私が期待するもの:

  • flatMapStreamを与えるMap.Entry<B, C>
  • collect(Collectors.groupingBy(...))Map.Entry<B, C>に適用されてを返す関数を受け取りB、 の値を収集しCますList<C>

しかし、文字通りコンパイルされません。

非静的メソッドは静的コンテキストから参照できません

Map.Entry::getKey最後の行で。

誰かが何が間違っているか、または私が望むものを達成するための正しい方法を説明できますか?

4

2 に答える 2

14

ストリームはMap.Entryオブジェクトで構成されていますが、収集したいのは、実際にはエントリ自体ではなく、エントリの値です。現在のコードでは、Map<B, List<Map.Entry<B, C>>>.

そのため、 への呼び出しが欠落しているだけですCollectors.mapping。このコレクターは、指定されたマッパー関数を使用して Stream 要素をマップし、その結果を下流のコンテナーに収集します。この場合、マッパーはMap.Entry::getValue(つまり、マップ エントリから値を返す) であり、ダウンストリーム コレクターは に収集しListます。

public <A, B, C> Map<B, List<C>> groupsByInnerKey(Map<A, Map<B, C>> input) {
    return input.values()
            .stream()
            .flatMap(it -> it.entrySet().stream())
            .collect(Collectors.groupingBy(
                 Map.Entry::getKey,
                 Collectors.mapping(Map.Entry::getValue, Collectors.toList())
            ));
}
于 2016-01-11T11:11:12.597 に答える
8

ストリーム パイプラインはMap<B, List<Map.Entry<B,C>>>ではなく を返しますMap<B, List<C>>

を取得するには、にマップされるMap<B, List<C>>a を追加する必要があります。mappingMap.Entry<B,C>C

return input.entrySet()
        .stream()
        .flatMap(it -> it.getValue().entrySet().stream())
        .collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.mapping(Map.Entry::getValue,Collectors.toList())));
于 2016-01-11T11:10:04.537 に答える