JavaのStream APIは、コレクションや配列、Streamなどの要素を逐次処理するためのAPIです。Stream APIは、要素のフィルタリング、変換、集約などの様々な操作を提供しており、複雑な処理を簡潔に記述することができます。
Stream APIでStreamを生成元は、様々なクラスに定義されていますが、主に以下の方法があります。
Streamが保持するデータは、オブジェクト参照か基本データ型の値でint, long, doubleの3つのデータ型がサポートされています。
この記事ではストリームの生成元について詳しく説明します。
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);
}
}
配列から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);
}
}
値から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);
}
}
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);
}
}
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の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操作を適用することもできます。
ファイルから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の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.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);
}
}
その他ストリームを生成するメソッドは多くのクラスに定義されています。