Java のストリームフィルター
- 
          
            Java の filter()およびcollect()メソッドを使用したストリーム
- 
          
            Java の filter()およびforEach()メソッドを使用したストリーム
- 
          
            filter()と Java の複数の条件を使用したストリーム
- 
          
            Java で filter()とmap()を使用してストリーミング
- 
          
            Java でいくつかの filter()メソッドをスタッキングしてストリーミング
 
このチュートリアルでは、Java のストリーム API とその filter() メソッドを紹介します。Java では、ストリームはオブジェクトのコレクションです。
ストリームはデータを格納しないため、データ構造ではありません。ストリームにはさまざまなメソッドがあり、それらをパイプライン化して目的の結果を得ることができます。
それらのメソッドの 1つは、filter メソッドです。この記事の filter() 操作を使用したさまざまな例を見ていきます。
まず、filter() 操作について理解しましょう。filter() メソッドは、引数として渡された述語に一致する要素を持つ新しいストリームを返します。
つまり、filter() 操作を使用して、着信ストリームをフィルタリングし、新しいストリームを出力します。このメソッドの構文は次のとおりです。
Stream<T> filter(Predicate<? super T> predicate)
述語は関数型インターフェースです。つまり、ここでラムダ関数またはメソッド参照を渡すことができます。いくつかの例を見てみましょう。
Java の filter() および collect() メソッドを使用したストリーム
collect() 操作は、端末操作の一種です。
ターミナル操作は、結果を生成するために最後にストリームに適用されます。ターミナルオペレーターが適用されると、ストリームは消費され、消費できなくなります。
collect() 操作は、中間操作の出力を返します。また、出力を目的のデータ構造に変換するために使用することもできます。以下の例を見てください。
クラス内のすべての生徒のリストがあり、1 人を除くすべての生徒の名前を含む新しいリストを作成するとします。1 人の生徒が学校を辞めたとします。
この与えられたコードによってこれを行うことができます。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<String> students = Arrays.asList("Kashish", "Riyan", "Ritu");
    List<String> new_students =
        students.stream().filter(sName -> !"Riyan".equals(sName)).collect(Collectors.toList());
    new_students.forEach(System.out::println);
  }
}
出力:
Kashish
Ritu
このコードでは、最初に、学生名のストリームが作成されます。
次に、述語を使用してストリームがフィルタリングされます。すべての名前が Riyan と等しくありません。filter 操作は、この述語を満たすすべての要素を含む新しいストリームを生成します。
次に、新しく作成されたストリームは、collect 操作を使用してリストに変換されます。
Java の filter() および forEach() メソッドを使用したストリーム
    
forEach() メソッドもターミナル操作です。引数として渡された関数を各ストリーム要素に適用します。
これは foreach ループのように機能しますが、ストリームに対してのみ機能します。以下の例を参照してください。
5 で割り切れるすべての数値を出力するとします。以下のコードはそのように機能します。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 11, 10, 25);
    numbers.stream().filter(n -> n % 5 == 0).forEach(System.out::println);
  }
}
出力:
5
10
25
filter() と Java の複数の条件を使用したストリーム
論理演算子を使用して filter() 操作に複数の条件を渡して、より洗練された結果を得ることができます。5 で割り切れるすべての要素と 10 より大きい要素を見つけたいとします。以下の例を参照してください。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 11, 10, 25);
    numbers.stream().filter(n -> n % 5 == 0 && n > 10).forEach(System.out::println);
  }
}
出力:
25
Java で filter() と map() を使用してストリーミング
map() 操作は、forEach() 操作と同じです。
ストリームの各要素に関数を適用します。これは、端末操作ではなく中間操作です。
5 で割り切れるすべての要素を 2 乗する必要があるとします。これは、filter および map 操作をパイプライン化することで実行できます。
以下の例を参照してください。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 21, 11, 10, 25);
    List<Integer> new_numbers =
        numbers.stream().filter(n -> n % 5 == 0).map(x -> x * x).collect(Collectors.toList());
    new_numbers.forEach(System.out::println);
  }
}
出力:
25
100
625
上記のコードでは、最初に整数のリストがフィルタリングされます。リストをフィルタリングした後、ストリームに残っている各要素は、map() 操作を使用して二乗されます。
最後に、ストリームをリストに変換し、new_numbers リストに保存します。
Java でいくつかの filter() メソッドをスタッキングしてストリーミング
    
filter() メソッドを次々に適用することでスタックし、より洗練された結果を得ることができます。
最初に長さが 3 より大きい文字列をフィルタリングし、次に stack をサブストリングとして含む文字列をフィルタリングするとします。以下のコード例を使用してこれを行うことができます。
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<String> str = Arrays.asList("Hello", "I", "Love", "Delftstack");
    List<String> new_string = str.stream()
                                  .filter(n -> n.length() > 3)
                                  .filter(n -> n.contains("stack"))
                                  .collect(Collectors.toList());
    new_string.forEach(System.out::println);
  }
}
出力:
Delftstack
上記のコードは、&&演算子を使用して複数の条件を使用するのと同じであることに注意してください。以下を見てください:
import java.util.*;
import java.util.stream.Collectors;
public class MyClass {
  public static void main(String args[]) {
    List<String> str = Arrays.asList("Hello", "I", "Love", "Delftstack");
    List<String> new_string = str.stream()
                                  .filter(n -> n.length() > 3 && n.contains("stack"))
                                  .collect(Collectors.toList());
    new_string.forEach(System.out::println);
  }
}
出力:
Delftstack
関連記事 - Java Method
- Java Streams での flush() メソッドの使用
- Java で wait() メソッドと notify() メソッドを使用する
- Java でのメソッド チェーン
- Java での静的メソッドのオーバーライドとオーバーロード
- Java のオプションの ifPresent()
- Java のカスタム ヘルパー メソッド