2016-02-09 5 views
10

Map文字列をListにマッピングすると、Java Streamsを使用してTRUEが1つ以上のリスト要素がありましたか?マップ内のすべてのリストが空の場合は、FALSEを返します。マップ内のすべてのList値が空であるか空でない場合は、Streamsを使用して

Map< String , List<String> > map = … 

この従来のコードをStreamsで置き換えることはできますか?

// See if any diffs were found. Loop through the Map, look at each List of diffs to see if non-empty. 
boolean anyElementsInAnyList = false; 
for (List<String> list : map.values()) { 
    if (!list.isEmpty()) { 
     anyElementsInAnyList = true; 
     break; 
    } 
} 

最初の発見後に試験を中断することができます。すべてのマップ値(すべてのリスト)を調べる必要はありません。効率を上げるために、ストリームが同じストップ・オン・ファースト・ファインディング(「短絡」操作)を行うことができればいいでしょう。

+1

このJavaストリームを意味しますか? http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html –

+0

ループで 'ブール'の代わりに 'ブール'を使用する理由は何ですか? – Holger

答えて

14

Java 8では、すべてのリストが空ではないことを確認できます。

boolean anyNonEmpty = !map.values().stream().allMatch(List::isEmpty); 
+1

'allMatch'と' anyMatch'を使って[answer by rgettman](http://stackoverflow.com/a/35282464/642706)のコードの逆を調べることに興味があります。このアプローチのように、ここでは「短絡」操作を利用することはできません。したがって、短絡するrgettmanほど効率的ではありません。 –

+5

@BasilBourque 'allMatch'メソッドも短絡しています。 – rgettman

+2

@Basil Bourque:メソッド名で行かないでください。[documentation](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#allMatch -java.util.function.Predicate-): "*これは短絡端末操作です。*" – Holger

7

ストリームの任意の要素がPredicateと一致するかどうかを確認するthe anyMatch methodを使用します。ここでは、エントリの値(リスト)は空ではないという述語です。

boolean anyNonEmpty = map.entrySet() 
    .stream() 
    .anyMatch(entry -> !entry.getValue().isEmpty()); 
+0

@hotkey 'entrySet'を' values'で置き換えることができ、述語で '!list.isEmpty'にまっすぐ行くとコメントしたはずです。 – rgettman

+0

よかった、ありがとう!この方法は、この方法は[短絡端末操作](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps)です。したがって、このストリームは、マップ内のすべての値をチェックしないという効率性のいくつかを持つ必要があります。どうやら[この質問](http://stackoverflow.com/q/27235839/642706)に従って、この利点が並行して(マルチスレッドで)働いているようです。 –

+0

@rgettman、申し訳ありません。 – hotkey

0
int size = Map.entrySet().stream() 
          .map(entry -> entry.getValue()) 
          .flatMap(list -> list.stream()) 
          .size(); 
if(size==0) 
    return Boolean.False; 
else 
    return Boolean.True; 

このコードでは、これはあなたの仕事のために役立つかもしれない簡単なものです。

+1

ダウン投票?あなたの批判的なコメントをあなたの投票と一緒に残してください。これは、面白い別のアプローチで、教育、堅実な答えです。この質問のシナリオには最適ではありませんが、シナリオが少し異なる他の読者にとっては非常に便利です。 –

+2

私はdownvoteしませんでしたが、批判するいくつかの明白なことがあります。まず、正しい変数名 'map'の代わりに' Map'(その名前の型と混同しやすい)を使用すると、 'entrySet()'をストリームして次のステップは、とりわけ質問がすでに値()の存在を示唆しているため、最初にストリームすることができます。さらに、 'Stream'に' size() 'メソッドはなく、存在していても、すべての要素を数えることは一般的に短絡することができないので、ここではリソースの無駄でした。 'return size == 0;'について話さないでください... – Holger