Java の Stream API を使用してコレクションをフィルタリングする方法

JavaJavaBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

Java Stream API は、データのコレクションを操作するための強力で汎用性の高い方法を提供します。このチュートリアルでは、Stream API を活用してコレクションをフィルタリングする方法を探り、必要なデータを効率的に抽出する方法を学びます。Java の初心者でも、経験豊富な開発者でも、このガイドを通じてデータ処理タスクを合理化するための知識とスキルを身につけることができます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java/DataStructuresGroup -.-> java/collections_methods("Collections Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/hashmap("HashMap") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/iterator("Iterator") java/FileandIOManagementGroup -.-> java/files("Files") java/FileandIOManagementGroup -.-> java/read_files("Read Files") java/FileandIOManagementGroup -.-> java/io("IO") java/FileandIOManagementGroup -.-> java/stream("Stream") subgraph Lab Skills java/collections_methods -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/arraylist -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/hashmap -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/iterator -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/files -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/read_files -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/io -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} java/stream -.-> lab-415586{{"Java の Stream API を使用してコレクションをフィルタリングする方法"}} end

Java Stream API のはじめに

Java Stream API は、Java 8 で導入された強力な機能で、宣言的かつ関数型スタイルでデータのコレクションを処理することができます。ストリームは、明示的な反復処理や可変状態を必要とせずに、フィルタリング、マッピング、ソート、リダクションなど、さまざまなデータ操作を行う方法を提供します。

ストリームの理解

ストリームは、要素のシーケンスであり、それらの要素に対してさまざまな演算を行うことができます。ストリームは、コレクション、配列、または I/O リソースなど、さまざまなデータソースから作成することができます。ストリームは、複数の操作をチェーンすることができる流暢な API を提供し、コードをより表現力豊かで読みやすくします。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();
stream.filter(n -> n % 2 == 0)
     .map(n -> n * 2)
     .forEach(System.out::println);

上記の例では、整数のリストからストリームを作成し、偶数をフィルタリングし、それらを 2 倍の値にマッピングしてから、結果を出力しています。

ストリームを使用する利点

  1. 宣言的プログラミング:ストリームを使用すると、どのように実現するかではなく、何を達成したいかに焦点を当てて、より宣言的な方法で意図を表現することができます。
  2. 並列処理:ストリームは簡単に並列化できるため、マルチコアプロセッサを活用してパフォーマンスを向上させることができます。
  3. 遅延評価:ストリームは遅延評価されるため、最終結果が必要になったときにのみ操作が実行され、効率を向上させることができます。
  4. 流暢な API:ストリーム API は、複数の操作をチェーンする流暢で表現力豊かな方法を提供し、コードをより読みやすく保守しやすくします。

ストリーム操作の探索

ストリームは、データを操作するために使用できる幅広い操作を提供します。最も一般的な操作には、以下のようなものがあります。

  • フィルタリング:与えられた述語に基づいて要素を選択する。
  • マッピング:関数を使用して要素を変換する。
  • ソート:コンパレータに基づいて要素を並べ替える。
  • リダクション:要素を単一の結果に結合する。
  • 収集:結果を新しいデータ構造に収集する。

次のセクションでは、コレクションをフィルタリングするための Stream API の具体的な使い方について詳しく見ていきます。

ストリームを使ったコレクションのフィルタリング

フィルタリングは、Java Stream API を使ってコレクションに対して行われる最も一般的な操作の 1 つです。フィルタリングを使うと、与えられた述語に基づいてコレクションから要素のサブセットを選択することができます。

フィルターの適用

filter() メソッドは、ストリームにフィルターを適用するために使用されます。このメソッドは、フィルタリング条件を表すラムダ式またはメソッド参照を引数として取ります。

List<String> names = Arrays.asList("John", "Jane", "Bob", "Alice");
Stream<String> filteredNames = names.stream()
                                   .filter(name -> name.startsWith("J"));
filteredNames.forEach(System.out::println);

上記の例では、名前のリストからストリームを作成し、filter() メソッドを使って、文字「J」で始まる名前のみを選択しています。

複数のフィルターをチェーンする

複数の filter() 呼び出しをチェーンすることで、ストリームに複数のフィルタリング条件を適用することができます。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> filteredNumbers = numbers.stream()
                                        .filter(n -> n % 2 == 0)
                                        .filter(n -> n > 5);
filteredNumbers.forEach(System.out::println);

この例では、まず偶数のみを選択するように数値をフィルタリングし、次に 5 より大きい偶数のみを選択するために 2 番目のフィルターを適用しています。

フィルターと他の操作を組み合わせる

フィルタリングは、マッピング、ソート、リダクションなどの他のストリーム操作と組み合わせて、より複雑なデータ変換を行うことができます。

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

List<String> youngAdultNames = persons.stream()
                                     .filter(p -> p.getAge() >= 18 && p.getAge() < 30)
                                     .map(Person::getName)
                                     .collect(Collectors.toList());

System.out.println(youngAdultNames);

この例では、まず Person オブジェクトのリストをフィルタリングして若年成人(18 歳以上 30 歳未満)のみを選択し、次に各 Person オブジェクトの Name プロパティをマッピングし、最後に結果を新しいリストに収集しています。

Java Stream API を使ったフィルタリングの威力を理解することで、データのコレクションを効果的に操作および処理することができます。次のセクションでは、フィルターを適用するより実践的な例を探っていきます。

フィルターの適用:実践的な例

これで Java Stream API を使ったフィルタリングの基本をしっかりと理解できたと思います。では、知識を定着させるためにいくつかの実践的な例を見ていきましょう。

文字列のフィルタリング

文字列のリストがあり、特定の長さを持つものや、特定の文字で始まるものだけを選択したいとします。

List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");

// 文字数が 5 より多い単語をフィルタリング
List<String> longWords = words.stream()
                             .filter(word -> word.length() > 5)
                             .collect(Collectors.toList());
System.out.println(longWords); // [banana, cherry, elderberry]

// 'a' で始まる単語をフィルタリング
List<String> wordsStartingWithA = words.stream()
                                     .filter(word -> word.startsWith("a"))
                                     .collect(Collectors.toList());
System.out.println(wordsStartingWithA); // [apple, date]

数値のフィルタリング

Stream API を使って、整数や倍精度浮動小数点数などの数値データをフィルタリングすることもできます。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 偶数をフィルタリング
List<Integer> evenNumbers = numbers.stream()
                                 .filter(n -> n % 2 == 0)
                                 .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

// 5 より大きい数値をフィルタリング
List<Integer> numbersGreaterThan5 = numbers.stream()
                                         .filter(n -> n > 5)
                                         .collect(Collectors.toList());
System.out.println(numbersGreaterThan5); // [6, 7, 8, 9, 10]

カスタムオブジェクトのフィルタリング

Person オブジェクトなどのカスタムオブジェクトのコレクションにもフィルターを適用することができます。

class Person {
    private String name;
    private int age;

    // Getters, setters, and constructor
}

List<Person> persons = Arrays.asList(
    new Person("John", 30),
    new Person("Jane", 25),
    new Person("Bob", 35),
    new Person("Alice", 28)
);

// 30 歳より年上の人をフィルタリング
List<Person> personsOlderThan30 = persons.stream()
                                       .filter(p -> p.getAge() > 30)
                                       .collect(Collectors.toList());
System.out.println(personsOlderThan30); // [Person(name=Bob, age=35)]

// 名前が 'J' で始まる人をフィルタリング
List<Person> personsWithNameStartingWithJ = persons.stream()
                                                 .filter(p -> p.getName().startsWith("J"))
                                                 .collect(Collectors.toList());
System.out.println(personsWithNameStartingWithJ); // [Person(name=John, age=30), Person(name=Jane, age=25)]

これらの実践的な例を見ることで、Java で filter() メソッドを使ってコレクションを効果的に操作する方法がもっと理解できたはずです。

まとめ

このチュートリアルを終えるころには、Java Stream API を使ってコレクションをフィルタリングする方法をしっかりと理解できるようになっているでしょう。filter()distinct()limit() などのさまざまなフィルタリングメソッドと、それらを特定のユースケースに適用する方法を学びます。得られた知識を活かして、より効率的で保守しやすい Java コードを書き、データ処理のワークフローを最適化し、Stream API の全ての可能性を引き出すことができるようになります。