Java Stream API

Java 8から導入されたStream APIは、コレクションや配列などの要素を高階関数的に扱うためのAPIです。ストリームは、複数の処理をまとめて行うことができるため、コードの記述量を減らすことができます。

この記事では、JavaのStreamAPIの概要について説明していきます。

Java Streamの特徴

Java Streamの特徴は以下の通りです。

  • データを逐次処理するための機能を提供するAPI
  • 要素を集約するための機能を提供するAPI
  • データを変換するための機能を提供するAPI

データを逐次処理するための機能を提供するAPI

Java Streamは、要素を一度に1つずつ処理していく逐次処理を行うことができます。つまり、1つの要素を処理し終わった後に、次の要素を処理するという形でデータを処理していきます。これによって、膨大な数の要素を扱う場合でも、メモリ使用量を抑えることができます。

要素を集約するための機能を提供するAPI

Java Streamは、複数の要素をまとめて集約することができます。例えば、数値型のデータを合計する場合、以下のように書くことができます。

import java.util.stream.*;

class Main{
    public static void main(String[] args){
        int sum = IntStream.of(1, 2, 3, 4, 5)
                   .sum();
        System.out.println(sum);
    }
}

これによって、要素を合計することができます。このように、Java Streamは要素を集約する機能を提供しています。

データを変換するための機能を提供するAPI

Java Streamは、要素を変換するための機能を提供しています。例えば、要素の大文字を小文字に変換する場合、以下のように書くことができます。

import java.util.stream.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
class Main{
    public static void main(String[] args){
        List<String> list = Arrays.asList("A", "B", "C");
        List<String> lowerCaseList = list.stream()
                                         .map(String::toLowerCase)
                                         .collect(Collectors.toList());
        System.out.println(lowerCaseList);
    }
}

これによって、要素の大文字を小文字に変換することができます。このように、Java Streamは要素を変換する機能を提供しています。

以上のように、Java Streamは、逐次処理、要素の集約、要素の変換など、様々な機能を提供しています。これらの機能を組み合わせることで、複雑なデータ処理を簡単に行うことができます。

Java Streamの利用方法

Java Streamの利用方法は、以下の手順で行います。

  • Streamの生成
  • 中間操作(複数可能)
  • 終端操作

Java Streamの生成

Streamの生成は、配列や文字列、コレクションから行うことができます。以下は、ListからStreamを生成する例です。

import java.util.stream.*;
import java.util.List;
import java.util.Arrays;

class Main{
    public static void main(String[] args){
        List<String> list = Arrays.asList("A", "B", "C");
        // コレクションListからStreamの生成
        Stream<String> stream = list.stream();
        // Streamの要素を出力する
        stream.forEach(System.out::println);      
    }
}

以下は配列からStreamを生成する例です。

import java.util.stream.*;
import java.util.Arrays;

class Main{
    public static void main(String[] args){
        int[] array = {1,2,3,4,5};

        // 配列からIntStreamを生成する
        IntStream stream = Arrays.stream(array);

        // Streamの要素を出力する
        stream.forEach(System.out::println);
    }
}

以下は文字列からIntStreamを生成する例です。

import java.util.stream.*;
import java.util.Arrays;
class Main{
    public static void main(String[] args){
        String str = "Java Stream Sample";

        // 文字列列からIntStreamを生成する
        IntStream stream = str.chars();

        // Streamの要素を出力する
        stream.forEach(System.out::println);
    }
}

Java Stream 中間操作

中間操作は、複数の中間操作を連結して使用することができます。以下は、フィルタリングとマッピングの2つの中間操作を使用する例です。

import java.util.stream.*;
import java.util.Arrays;
import java.util.List;
class Main{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry", "avocado");
        Stream<String> stream = list.stream()
            .filter(s -> s.startsWith("a")) // 中間操作filter
            .map(s -> s.toUpperCase()); // 中間操作map

        // Streamの要素を出力する
        stream.forEach(System.out::println);
    }
}

Java Stream 終端操作

終端操作は、中間操作を終了させてストリームを閉じます。以下は、forEachメソッドを使用して、各要素を出力する例です。

import java.util.stream.*;
import java.util.Arrays;
import java.util.List;
class Main{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry");
        list.stream()
        .forEach(System.out::println);
    }
}

以下はStreamをコレクションにする終端操作の例です。

import java.util.stream.*;
import java.util.Arrays;
import java.util.List;
class Main{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("apple", "banana", "cherry", "avocado");

        List<String> list2 = list.stream()
            .filter(s -> s.startsWith("a")) // 中間操作filter
            .map(s -> s.toUpperCase()) // 中間操作map
            .collect(Collectors.toList()); // 終端操作

        System.out.println(list2);
    }
}

Java Streamの注意点

Java Streamを使用する際に注意する点は以下の通りです。

  • 中間操作は遅延実行されるため、終端操作が呼び出されるまで処理が実行されない。
  • Streamは一度しか使えないため、再利用するには再度生成する必要がある。
  • Streamの要素が並列で処理されるため、並列処理に問題がある場合は処理が正しく行われない可能性がある。

以上が、Java Streamについての解説です。Java Streamは、複数の要素を効率的に処理するためのAPIであり、コードの可読性やメンテナンス性の向上につながるため、積極的に活用していくことが望まれます。

この記事を書いた人

著者の画像

Jeffry Alvarado

Ex-Facebook Engineer 大学ではコンピュータサイエンスを専攻し、在学中に複数のインターンシップを経験。コンピュータサイエンスが学習できるプラットフォームRecursionを創業し、CTOとしてカリキュラム作成、ソフトウェア開発を担当。


ツイート