Java Streamの生成

JavaのStream APIは、コレクションや配列、Streamなどの要素を逐次処理するためのAPIです。Stream APIは、要素のフィルタリング、変換、集約などの様々な操作を提供しており、複雑な処理を簡潔に記述することができます。

Stream APIでStreamを生成元は、様々なクラスに定義されていますが、主に以下の方法があります。

  • コレクションから生成
  • 配列から生成
  • ofメソッドで生成
  • 疑似乱数から生成
  • ファイルから生成する

Streamが保持するデータは、オブジェクト参照か基本データ型の値でint, long, doubleの3つのデータ型がサポートされています。

この記事ではストリームの生成元について詳しく説明します。

Java コレクションからStreamを生成する

Stream APIは、Javaのコレクションフレームワークに対応しています。コレクションからStreamを生成する場合は、以下のようにstreamメソッドを呼び出すことで生成することができます。

streamメソッドは、CollectionインタフェースにStreamSupportクラスのstreamメソッドを返すよう定義されていて、CollectionのサブクラスであるListなどで利用できます。

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()を使用して生成
        Stream<String> stream = list.stream();

        // streamの要素を表示
        stream.forEach(System.out::println);  
    }
}

Java 配列からStreamを生成する

配列からStreamを生成する場合は、Arrays.stream()メソッドを使用して生成することができます。

Arraysのstreamメソッドはオブジェクト参照および、int, double, long型の配列を受け取ることができるようオーバーライドされています。基本データ型の場合はそれぞれ、IntStream, DoubleStream, LongStreamを生成して返します。

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

import java.util.stream.*;
import java.util.Arrays;
import java.util.List;
class Main{
    public static void main(String[] args) {
        // String型の配列
        String[] array = {"apple", "banana", "orange"};
        // streamメソッドでstreamを生成
        Stream<String> stream = Arrays.stream(array);

        // streamの要素を表示
        stream.forEach(System.out::println);  
    }
}

int, double, longの場合は以下になります。

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

class Main{
    public static void main(String[] args) {
        // int型の配列
        int[] intArray = {1,2,3,4,5};
        // streamメソッドでstreamを生成
        IntStream intStream = Arrays.stream(intArray);
        // streamの要素を表示
        intStream.forEach(System.out::println);  

        // double型の配列
        double[] doubleArray = {1,2,3,4,5};
        // streamメソッドでstreamを生成
        DoubleStream doubleStream = Arrays.stream(doubleArray);
        // streamの要素を表示
        doubleStream.forEach(System.out::println); 

        // long型の配列
        long[] longArray = {10000000000L,20000000000L,30000000000L,40000000000L,50000000000L};
        // streamメソッドでstreamを生成
        LongStream longStream = Arrays.stream(longArray);
        // streamの要素を表示
        longStream.forEach(System.out::println);  
    }
}

Java ofメソッドでストリームを生成する

値からStreamを生成する場合は、of()メソッドを使用して生成することができます。ofメソッドは、StreamクラスやIntStreamクラスなどに定義されています。

以下は、ofメソッドでStreamを生成する例です。

import java.util.stream.*;

class Main{
    public static void main(String[] args) {
        // of メソッドでstreamを生成
        Stream<String> stream = Stream.of("apple", "banana", "orange");
        // streamの要素を表示
        stream.forEach(System.out::println);  

        IntStream intStream = IntStream.of(1,2,3,4,5);
        intStream.forEach(System.out::println);

        DoubleStream doubleStream = DoubleStream.of(1,2,3,4,5);
        doubleStream.forEach(System.out::println);

        LongStream longStream = LongStream.of(10000000000L,20000000000L,30000000000L,40000000000L,50000000000L);
        longStream.forEach(System.out::println);
    }
}

Java range、rangeClosedからStreamを生成する

range, rangeClosedメソッドを使うと、指定範囲のストリームを生成することができます。rangeとrangeClosedの違いは第二引数で指定した値を含むか含まないかです。

range, rangeClosedともにint型、long型のみに対応しており、double型はありません。戻り値はIntStream, LongStreamです。

import java.util.stream.*;

class Main{
    public static void main(String[] args) {
        IntStream intStream = IntStream.range(1,5);
        intStream.forEach(System.out::println);

        IntStream intStreamClosed = IntStream.rangeClosed(1,5);
        intStreamClosed.forEach(System.out::println);

        LongStream longStream = LongStream.range(50000000001L,50000000005L);
        longStream.forEach(System.out::println);

        LongStream longStreamClosed = LongStream.rangeClosed(50000000001L,50000000005L);
        longStreamClosed.forEach(System.out::println);
    }
}

Java generateメソッドでストリームを生成する

generate()メソッドは、指定された関数を使用して無限の要素を生成するストリームを作成します。このメソッドは、ストリームの要素を生成するためにSupplier関数を受け取ります。

以下は、Stream.generate()メソッドを使用して、10個のランダムな整数からなる無限ストリームを生成する例です。

import java.util.stream.*;
import java.util.Random;

class Main{
    public static void main(String[] args) {
        Random random = new Random();
        Stream<Integer> stream = Stream.generate(() -> random.nextInt(100)).limit(10);
        stream.forEach(System.out::println);
    }
}

この例では、Randomクラスを使用して、0から99の範囲内のランダムな整数を生成するSupplier関数を作成しています。Stream.generate()メソッドにこのSupplier関数を渡すことで、無限ストリームを生成しています。

しかし、無限ストリームを直接使用することはできません。代わりにlimit()メソッドを使用して、生成される要素の数を制限しています。この例では、10個の要素を生成しています。最後にforEach()メソッドを使用して、ストリームの各要素を出力しています。

このようにStream.generate()メソッドを使用することで、無限の要素を持つストリームを生成できます。しかし、無限ストリームを処理する際には、制限を設ける必要があります。また、生成される要素が常に同じである場合、ストリームを処理するための効率的な方法を考慮する必要があります。

Java charsメソッドでStreamを生成する

JavaのString.chars()メソッドは、指定された文字列の文字を含むIntStreamを生成します。このIntStreamには、文字列内の各文字に対応するUnicodeコードポイントが含まれます。

以下は、String.chars()メソッドを使用して、文字列からIntStreamを生成する例です。

import java.util.stream.*;

class Main{
    public static void main(String[] args) {
        String str = "HelloWorld";
        IntStream intStream = str.chars();
        intStream.forEach(System.out::println);
    }
}

この例では、Stringクラスのchars()メソッドを使用して、"Hello World"という文字列からIntStreamを生成しています。生成されたIntStreamには、H,e,l,l,o,W,o,r,l,dのUnicodeコードポイントが含まれます。最後にforEach()メソッドを使用して、IntStreamの各要素を出力しています。

このようにString.chars()メソッドを使用することで、文字列内の各文字に対応するUnicodeコードポイントを含むIntStreamを簡単に生成できます。生成されたIntStreamには、mapToObj()メソッドを使用して文字列に変換し、文字列を操作するためのStream操作を適用することもできます。

Java ファイルからストリームを生成する

ファイルからStreamを生成する場合は、Files.lines()メソッドを使用して生成することができます。以下は、ファイルから文字列を読み込んでStreamを生成する例です。

Path path = Paths.get("sample.txt");

try (Stream<String> stream = Files.lines(path)) {
    stream.forEach(System.out::println);
} catch (IOException e) {
    e.printStackTrace();
}

上記のコードではFiles.lines()メソッドを使用して、sample.txtファイルからStreamを生成しています。生成したStreamは、try-with-resources構文を使用して自動的にクローズされるようにしています。

以上が、JavaのStream APIでStreamを生成するための4つの方法についての説明です。これらの方法を組み合わせることで、複雑な処理を簡潔に記述することができます。

Java 乱数でStreamを生成する

JavaのRandom.ints()メソッドは、指定された範囲内のランダムな整数を含むIntStreamを生成します。このメソッドは、Randomクラスのインスタンスを受け取り、生成される整数の範囲、ストリームのサイズ、およびストリーム要素に適用する操作を指定することができます。

以下は、Random.ints()メソッドを使用して、0から99の範囲内の10個のランダムな整数からなるIntStreamを生成する例です。

import java.util.stream.*;
import java.util.Random;

class Main{
    public static void main(String[] args) {
        Random random = new Random();
        IntStream intStream = random.ints(10, 0, 100);
        intStream.forEach(System.out::println);
    }
}

Java MapからStreamを生成する

java.util.Mapはstreamを生成するためのメソッドが定義されていないため、entrySetメソッドなどを経由しSetに変換することでストリームを生成することができます。

以下は、MapからSetに変換しStreamを生成する例です。

import java.util.stream.*;
import java.util.Map;

class Main{
    public static void main(String[] args) {
        Map<String, String> map = Map.of("dog", "犬", "cat", "猫", "hamster", "ハムスター");
        map.entrySet()
            .stream()
            .forEach(System.out::println);
    }
}

Java その他Stream生成方法

その他ストリームを生成するメソッドは多くのクラスに定義されています。

  • concat(stream1, stream2)
  • String codePoints()
  • Random longs(), doubles()
  • empty()
  • BufferReader lines()
  • Files lines(), find(), list(), walk()

この記事を書いた人

著者の画像

Jeffry Alvarado

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


ツイート