2016-10-25 4 views
1

は、私はこれらの線に沿って何かあります内部ImmutableListを持つマップのネストされたグループ化?

Map<String, Map<String, List<SomeClass>>> someMap = 
    .... (streams and filtering, etc.) 
    .collect(Collectors.groupingBy(
     x -> getSomeComputedAttribute(x), 
     Collectors.groupingBy(x -> getSomeOtherComputedAttribute(x)); 

これ、これまでのところ、正常に動作している - 私は正しい値を取得していますが、しかし、問題は、私はImmutableListにリストを有効にする必要があります。これを行う簡単な方法は何ですか?

答えて

3

が既にpointed out by Louis Wasserman、最も簡単な解決策を使用してListに収集するコレクタを内蔵しており、後処理工程でImmutableListに回収要素を転送:

Map<String, Map<String, List<SomeClass>>> someMap = 
    /* your stream operation */ 
    .collect(groupingBy(x -> getSomeComputedAttribute(x), 
     groupingBy(x -> getSomeOtherComputedAttribute(x), 
        collectingAndThen(toList(), ImmutableList::copyOf)))); 

これは、もちろん、リストの内容全体をコピーするというわずかなパフォーマンスの欠点があります。

自然な解決策は、ビルダーベースのコレクターである。これはまだ、ほとんどすべてのケースでImmutableList構築するビルダーの内容がコピーされますよう

public static <T> Collector<T,?,List<T>> toImmutableList() { 
    return Collector.of(
     ImmutableList::<T>builder, 
     ImmutableList.Builder::add, 
     (b1,b2) -> b1.addAll(b2.build()), 
     ImmutableList.Builder::build); 
} 

Map<String, Map<String, List<SomeClass>>> someMap = 
    /* your stream operation */ 
    .collect(groupingBy(x -> getSomeComputedAttribute(x), 
     groupingBy(x -> getSomeOtherComputedAttribute(x), toImmutableList()))); 

しかし驚くのようにそれを使用し、これはそれだけのような、任意のパフォーマンスの向上を得ることはありません収集された要素の数が配列の容量と正確に一致する場合は、内部配列を共有します。

それでも、それは、また...将来的に


を更新グアバライブラリの利点を得ることができ、あなたはそれが本当に不変のリストのグアバを実装する必要があるかどうかを再検討することがあります。コピーステップなしで不変なリストを得ることができます:

2

Java-8以前のGuavaに制限されている場合 - すぐに提供されます - おそらく最も簡単な回避策(悪いことではありません)はcollectingAndThen(toList(), ImmutableList::copyOf)です。

+1

これは、キー機能の後にgroupingByの第2引数として使用します。また、Java 8の機能を備えたGuavaは現在リリースされていませんが、すぐにリリースされる予定です。 –

関連する問題