1. 確認

データ ストリームを連結する方法を学ぶことにすでに飽きているかもしれません。最終的にはデータを使って何かをしたいと考えています。

このStreamクラスには、ストリームを構築せず、ストリームに含まれるデータの種類を確認する 3 つの標準メソッドがあります。これらのメソッドは、anyMatch()allMatch()、およびですnoneMatch()

boolean anyMatch(rule)方法

このメソッドは、メソッドに渡されるルールを満たす要素がストリームに少なくとも 1 つあるかどうかをチェックします。そのような要素が存在する場合、メソッドは を返しtrue、存在しない場合はを返しますfalse

コード ノート
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).anyMatch(x -> x > 0);

false

最後の例では、最初にゼロ未満の要素のみを保持し、次に結果をチェックしてフィルタリングされた要素のいずれかがゼロより大きいかどうかを確認します。もちろん、そのような要素はもうありません。

ブール値 allMatch(rule) メソッド

このメソッドは、ストリーム内のすべての要素がルール (述語とも呼ばれます) に一致するかどうかをチェックします。ルールは引数としてメソッドに渡されます。

コード ノート
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(ゼロより大きいすべての要素)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(ゼロ以下の要素はありますか?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(ゼロ未満の要素は保持しました)

最後の例では、最初にゼロ未満の要素のみがフィルターを通過することを許可し、次に保持されているすべての要素がゼロ未満であるかどうかを確認します。チェックの結果は肯定的です。

ブール値 noneMatch(rule) メソッド

このnoneMatch()メソッドは、渡されたルールに一致する要素がストリームにないかどうかを確認します。やり方の真逆のようなものですanyMatch()

コード ノート
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).noneMatch(x -> x > 0);

true


2. ユーティリティ クラス:Optionalクラス

プログラマにとって参照を扱うのは非常に不便な場合がありますnull。たとえば、2 つの文字列を比較しているとします。両方の変数が でない場合はnull、単に を呼び出すだけでs1.equals(s2)すべてが機能します。しかし、s1その可能性があるnull場合は、問題を回避するためにこの状況を処理するコードを作成する必要がありますNullPointerException

プログラマがユーティリティ クラスを考案したのはこのためですOptional<T>。そのコードはおおよそ次のようになります。

コード ノート
class Optional<Type>
{
   private final Type value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <Type> Optional<Type> of(Type value)
   {
      return new Optional<Type>(value);
   }

   public boolean isPresent()
   {
      return value != null;
   }

   public boolean isEmpty()
   {
      return value == null;
   }

   public Type get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public Type orElse(Type other)
   {
      return value != null ? value : other;
   }

   public Type orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










値が以下であるかどうかを確認します。null



値が以下であるかどうかを確認します。null




格納されている値を返します。値が null の場合は例外をスローします。







格納されているnull以外の値を返します。または、格納された値が の場合はnull、メソッドの引数として渡された値を返します。



格納された非 null 値を返すか、値が null の場合は例外をスローします。

このクラスの目的は、単に T オブジェクト (型が T であるオブジェクトへの参照) を格納することです。オブジェクト内のオブジェクト参照はOptional<T>次のとおりですnull

このクラスを使用すると、プログラマーは少しきれいなコードを作成できます。比較してみましょう:

オプションの使用 オプションを使用しない
public void printString(String s)
{
   Optional<String> str = Optional.ofNullable(s);
   System.out.println(str.orElse(""));
}
public void printString(String s)
{
   String str = s != null ? s : "";
   System.out.println(str)
}

このメソッドを使用すると、オブジェクトに参照が保存されている場合でも、あるOptionalオブジェクトを別のオブジェクトと常に比較できます。Optionalequalsnull

簡単に言えば、このクラスを使用すると、オブジェクトが値を格納する場合のOptional「美しい」チェックと「美しい」アクションを作成できます。nullOptionalnull



3. 要素の検索

クラスに戻りましょうStream。このStreamクラスには、ストリーム内の要素を検索できるメソッドがさらに 4 つあります。これらのメソッドはfindFirst()、、、、およびです。findAny()min()max()

Optional<T> findFirst()方法

このfindFirst()メソッドは単にストリームの最初の要素を返します。それだけです。

ここで注目すべきさらに興味深い点は、メソッドがオブジェクトを返すのではなくTOptional<T>ラッパー オブジェクトを返すということです。これにより、オブジェクトの検索に失敗した後にメソッドが戻ることはなくなりますnull

例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello

より明確にするために、最後の行を複数の行に分割してみましょう。

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello

最後のget()メソッドは、オブジェクト内に格納されている値を単に取得するだけですOptional

Optional<T> findAny()方法

このfindAny()メソッドはストリームから任意の要素を返し、そこで終了します。このメソッドは に似ていますfindFirst()が、並列操作で使用されるストリームに最適です。

ストリームを並列処理する場合、ストリームの一部で要素がすでに見つかっている可能性がありますが、それが最初のものであるかどうかはまだ明らかではありません。

多くの要素がすべてのフィルターに一致しており、プログラマがそれらの最初の要素を正確に取得することが重要である場合、メソッドがfindFirst()呼び出される必要があります。プログラマが、実際には 0 または 1 つの要素がすべてのフィルターに一致することを知っている場合は、単に呼び出すだけで十分であり、findAny()この方が高速になります。

Optional<T> min(Comparator<T>)方法

このmin()メソッドは、オブジェクトを使用してcomparatorストリーム内のすべての要素を比較し、最小の要素を返します。コンパレータ オブジェクトを定義する最も便利な方法は、ラムダ関数を使用することです。

最短の文字列を検索する例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Optional<T> max(Comparator<T>)方法

このmax()メソッドは、オブジェクトを使用してcomparatorストリーム内のすべての要素を比較し、最大の要素を返します。コンパレータ オブジェクトを定義する最も便利な方法は、ラムダ関数を使用することです。

最長の文字列を検索する例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();