Java : BaseStream - API使用例
BaseStream (Java SE 19 & JDK 19) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
順次および並列の集約操作をサポートする要素シーケンスであるストリームの基底インタフェース。
BaseStream インタフェースは、各種ストリームのベースとなります。
ストリームの基本的なことは下記の記事にもまとめていますので、そちらもご参照ください。
final BaseStream<String, Stream<String>> stream = Stream.of("aaa", "bbb", "ccc");
System.out.println("isParallel : " + stream.isParallel());
System.out.println("-- iterator --");
final var iterator = stream.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 結果
// ↓
//isParallel : false
//-- iterator --
//aaa
//bbb
//ccc
メソッド
void close ()
このストリームを閉じます。その結果、このストリーム・パイプラインのすべてのクローズ・ハンドラが呼び出されます。
try-with-resources文を使うのがおすすめです。
final var path = Path.of("R:", "java-work", "aaa.txt");
System.out.println(path); // R:\java-work\aaa.txt
Files.writeString(path, """
aaa
bbb
""");
try (final var lines = Files.lines(path)) {
lines.forEach(System.out::println);
}
// 結果
// ↓
//aaa
//bbb
try-with-resources文を使わない例です。
final var path = Path.of("R:", "java-work", "aaa.txt");
System.out.println(path); // R:\java-work\aaa.txt
final var lines = Files.lines(path);
try {
lines.forEach(System.out::println);
} finally {
lines.close();
}
boolean isParallel ()
終端操作が実行された場合にこのストリームが並列実行されるかどうかを返します。
final var stream = Stream.of("a", "b", "c", "d");
System.out.println(stream.isParallel()); // false
final var list = stream.peek(s -> {
final var id = Thread.currentThread().getId();
System.out.println("thread id = " + id + " : " + s);
}).toList();
System.out.println("list : " + list);
// 結果
// ↓
//thread id = 1 : a
//thread id = 1 : b
//thread id = 1 : c
//thread id = 1 : d
//list : [a, b, c, d]
final var stream = Stream.of("a", "b", "c", "d").parallel();
System.out.println(stream.isParallel()); // true
final var list = stream.peek(s -> {
final var id = Thread.currentThread().getId();
System.out.println("thread id = " + id + " : " + s);
}).toList();
System.out.println("list : " + list);
// 結果
// ↓
//thread id = 21 : a
//thread id = 1 : d
//thread id = 19 : b
//thread id = 20 : c
//list : [a, b, c, d]
Iterator<T> iterator ()
このストリームの要素のイテレータを返します。
final var list = List.of("aaa", "bbb", "ccc");
final var iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 結果
// ↓
//aaa
//bbb
//ccc
S onClose (Runnable closeHandler)
追加のクローズ・ハンドラを含む同等のストリームを返します。
final var path = Path.of("R:", "java-work", "aaa.txt");
System.out.println(path); // R:\java-work\aaa.txt
Files.writeString(path, """
aaa
bbb
""");
System.out.println("--- before try ---");
try (final var lines = Files.lines(path).onClose(() -> {
System.out.println("onClose is called!");
})) {
lines.forEach(System.out::println);
}
System.out.println("--- after try ---");
// 結果
// ↓
//--- before try ---
//aaa
//bbb
//onClose is called!
//--- after try ---
final var path = Path.of("R:", "java-work", "aaa.txt");
System.out.println(path); // R:\java-work\aaa.txt
System.out.println("--- before try ---");
try (final var lines = Files.lines(path)) {
// 複数の登録も可能。
lines.onClose(() -> System.out.println("onClose 1"));
lines.onClose(() -> System.out.println("onClose 2"));
lines.onClose(() -> System.out.println("onClose 3"));
lines.forEach(System.out::println);
}
System.out.println("--- after try ---");
// 結果
// ↓
//--- before try ---
//aaa
//bbb
//onClose 1
//onClose 2
//onClose 3
//--- after try ---
S parallel ()
同等の並列ストリームを返します。
final var stream = Stream.of("a", "b", "c", "d");
System.out.println(stream.isParallel()); // false
final var parallelStream = stream.parallel();
System.out.println(stream.isParallel()); // true
final var list = parallelStream.peek(s -> {
final var id = Thread.currentThread().getId();
System.out.println("thread id = " + id + " : " + s);
}).toList();
System.out.println("list : " + list);
// 結果
// ↓
//thread id = 20 : c
//thread id = 19 : b
//thread id = 21 : a
//thread id = 1 : d
//list : [a, b, c, d]
S sequential ()
同等の順次ストリームを返します。
final var parallelStream = Stream.of("a", "b", "c", "d").parallel();
System.out.println(parallelStream.isParallel()); // true
final var stream = parallelStream.sequential();
System.out.println(stream.isParallel()); // false
final var list = parallelStream.peek(s -> {
final var id = Thread.currentThread().getId();
System.out.println("thread id = " + id + " : " + s);
}).toList();
System.out.println("list : " + list);
// 結果
// ↓
//thread id = 1 : a
//thread id = 1 : b
//thread id = 1 : c
//thread id = 1 : d
//list : [a, b, c, d]
Spliterator<T> spliterator ()
このストリームの要素のスプリッテレータを返します。
final var stream = Stream.of("aaa", "bbb", "ccc");
final var spliterator = stream.spliterator();
spliterator.forEachRemaining(System.out::println);
// 結果
// ↓
//aaa
//bbb
//ccc
S unordered ()
同等の順序付けされていないストリームを返します。
unorderedで順序付けを解除すると、ステートフルな操作(distinctやsortedなど)が効率よくなることがあります。
※処理時間は実行する環境によって変わります。
// 200000件の文字列のリストを作成
final var list = new ArrayList<String>();
for (int i = 0; i < 200000; i++) {
list.add(Integer.toHexString(i / 2));
}
// unorderedを使う例
{
final var start = System.nanoTime();
// 100回、map->distinct->collect を実行
for (int i = 0; i < 100; i++) {
final var stream = list.parallelStream().unordered();
final var result = stream.map(String::toUpperCase).distinct().toList();
}
final var time = System.nanoTime() - start;
System.out.println((time / 1000000000.0) + " 秒"); // 2.6085375 秒
}
// unorderedを使わない例
{
final var start = System.nanoTime();
// 100回、map->distinct->collect を実行
for (int i = 0; i < 100; i++) {
final var stream = list.parallelStream();
final var result = stream.map(String::toUpperCase).distinct().toList();
}
final var time = System.nanoTime() - start;
System.out.println((time / 1000000000.0) + " 秒"); // 3.4048646 秒
}