2016-10-12 28 views
1
List<Entity> entities = ... 
Map<Boolean, List<Entity>> entitiesByIsTest = entities.stream() 
         .collect(Collectors.groupingBy(Entity::isTest)); 

結果マップには、グループ化プロパティに存在する唯一のキーがあることは明らかです。これは、値の無限集合を持つ型に対しては、このように動作しなければなりません。しかし、列挙型/ブール型/その他の決定型はどうですか?StreamAPI Collectors.groupingBy nullの代わりに空のコレクション

空のコレクションの初期化を、以下のスニペットよりももっとエレガントに実装できますか?

if (entitiesByIsTest.get(true) == null) { 
    entitiesByIsTest.put(true, new ArrayList()); 
} 
+1

ハードが質問を理解します。あなたのコードの目的は何ですか? –

+0

目的は2つの独立したセットに分割し、いくつかの異なるアクションを実行することです。例えば、通常のエンティティを保持しますが、テストエンティティの数だけを保存します。 –

答えて

5

あなたは常に初期化Booleanキーと両方のマッピングをしたい場合は、正確に所望の特性を有しており、partitioningByを使用しています。

Map<Boolean, List<Entity>> entitiesByIsTest = entities.stream() 
         .collect(Collectors.partitioningBy(Entity::isTest)); 

キーがenumある場合は、groupingByに滞在する必要がありますが、あなたは唯一の存在であれば場合新しいArrayListを構築し、配置します

List<Entity> value=map.computeIfAbsent(key, x->new ArrayList<>()); 

と、その後のget操作を交換することができます以前のマッピングがなく、どちらの場合でも実際のマッピング値が返されます(putIfAbsentとは異なります)。

もちろん、あなたの代わりに1回の熱心な操作で全ての不在の値を追加することができます。

EnumSet.allOf(KeyType.class).forEach(key->map.computeIfAbsent(key, x->new ArrayList<>())); 
4

あなたはあなたがあなた自身のコレクタを書くことができ、そのキー

+0

ありがとう!いい視点ね。一つは、これは機能的なスタイルではないということです。私の主な目的は、明確なコードのようなストリームAPIのすべての利点を使用して、できるだけ多くの州を避けることです。 –

+0

あなたが求めていることは全く明らかではありません。あなたは既に 'groupingBy'のための解決策を持っています - それはenum、boolean、またはどんなタイプでも機能しています。この答えは、マップ内の空のコレクションを初期化する方法、2番目の質問に答えるものです。 –

0

用マップに何もない場合にのみ、新しい空のArrayListを追加する必要がありentitiesByIsTest.putIfAbsent(true,new ArrayList());を使用することができます。

Collectors.of(
    //**Initialize map with all of your values**//, 
    entity -> map.get(entity.isTest()).add(entity), 
    (left, right) -> right.forEach(r -> left.get(r.getKey()).addAll(r.getValue)); return r;) 
関連する問題