Java の Stream インターフェースに定義されているメソッドを見ていくシリーズ(目次)。 今回は Stream インターフェースに定義されている short-circuiting terminal operator に分類されるメソッドを見ていきます。 terminal operator は前回まで扱っていた「終端演算子」ですが「short-circuiting」は Java の && 演算子のような「ショートカット(演算子)」であることを表しています。 つまり、必要な結果が得られればそれ以降の要素に対する処理をやめて制御を返すような終端演算子です。 扱うメソッドは次の5つ:
// Match boolean allMatch(Predicate<? super T> predicate) boolean anyMatch(Predicate<? super T> predicate) boolean noneMatch(Predicate<? super T> predicate) // Find Optional<T> findFirst() Optional<T> findAny()
では Match と Find に分けて見ていきましょう。
Match
Match は Predicate オブジェクト(述語)*1を引数にとり、Stream の各要素に対してその述語に対応するテストを行い、その結果をまとめるメソッドです:メソッド | true を返す場合 | 空 Stream に対して | 備考 |
---|---|---|---|
allMatch() | 全ての要素に対して結果が true | true を返す | 各要素の結果値に対する論理積 |
anyMatch() | 少なくとも1つの要素に対して結果が true | false を返す | 各要素の結果値に対する論理和 |
noneMatch() | 全ての要素に対して結果が false | true を返す | anyMatch() の否定 |
返り値が false になるのは true を返す場合以外です。 空 Stream に対してもそれぞれ定められた boolean 値が返されます。 ではサンプルコード:
// Stream オブジェクトの生成メソッド public static Stream<String> stream(){ return Stream.of("Java", "Groovy", "Scala", "Clojure", "Kotlin", "Jython", "JRuby"); } // Predicate オブジェクト(述語) Predicate<String> starts_with_upper_case = s -> Character.isUpperCase(s.charAt(0)); Predicate<String> starts_with_J = s -> s.startsWith("J"); Predicate<String> ends_with_J = s -> s.endsWith("J"); // allMatch() assert stream().allMatch(starts_with_upper_case); assert !stream().allMatch(starts_with_J); assert !stream().allMatch(ends_with_J); assert Stream.<Boolean>empty().allMatch(arg -> true); // 常に true assert Stream.<Boolean>empty().allMatch(arg -> false); // anyMatch() assert stream().anyMatch(starts_with_upper_case); assert stream().anyMatch(starts_with_J); assert !stream().anyMatch(ends_with_J); assert !Stream.<Boolean>empty().anyMatch(arg -> true); // 常に false assert !Stream.<Boolean>empty().anyMatch(arg -> false); // noneMatch() assert !stream().noneMatch(starts_with_upper_case); assert !stream().noneMatch(starts_with_J); assert stream().noneMatch(ends_with_J); assert Stream.<Boolean>empty().noneMatch(arg -> true); // 常に true assert Stream.<Boolean>empty().noneMatch(arg -> false);
まぁ、結構分かりやすいメソッドではないでしょうか。 空 Stream に対する返り値がスッと頭に入ってくるかどうかってところかな。
Find
Find は要素を探索するメソッドです。 こちらは引数に何もとらず、それぞれ適切な要素の Optional を返します。 空 Stream に対しては空 Optional が返されます。- findFirst() ・・・ 出現順序に従って最初に位置する要素を返す
- findAny() ・・・ Stream 内のどれか1つの要素を返す
これらのメソッドは通常それ単体では使わず、次回にやる filter() メソッドなどとともに用いることが多いと思います。 というか、メソッドの引数にフィルターに相当する Predicate オブジェクトをとるバージョンもオーバーロードしてくれといてくれたらいいと思うのだが・・・ まぁ filter() メソッド使うのと変わらんが。 サンプルコードいってみよう:
// Stream オブジェクトの生成メソッド public static Stream<String> stream(){ return Stream.of("Java", "Groovy", "Scala", "Clojure", "Kotlin", "Jython", "JRuby"); } // テスト用の either() メソッド target が args の内のどれかと等しいなら true を、そうでなければ false を返します public static boolean either(String target, String... args){ for(String s : args){ if(target.equals(s))return true; } return false; } // Predicate オブジェクト(述語) Predicate<String> starts_with_J = s -> s.startsWith("J"); Predicate<String> ends_with_J = s -> s.endsWith("J"); // findFirst() assert stream().filter(starts_with_J).findFirst() .equals( Optional.of("Java") ); assert stream().filter(ends_with_J).findAny() .equals( Optional.empty() ); // findAny() String str = stream().filter(starts_with_J).findAny() .get(); assert either(str, "Java", "Jython", "JRuby"); assert stream().filter(ends_with_J).findAny() .equals( Optional.empty() );
結構使い勝手は良さそう。
次回は intermediate operators part 1 の予定。
- 作者: Martin Odersky,Lex Spoon,Bill Venners,羽生田栄一,水島宏太,長尾高弘
- 出版社/メーカー: インプレスジャパン
- 発売日: 2011/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 12人 クリック: 235回
- この商品を含むブログ (46件) を見る
*1:boolean 値を返す test() メソッドが定義されている。