広告

Java : BaseStream - API使用例

BaseStream (Java SE 21 & JDK 21) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様書のおともにどうぞ。


概要

順次および並列の集約操作をサポートする要素シーケンスであるストリームの基底インタフェース。

クラス構成

BaseStream インタフェースは、各種ストリームのベースとなります。
ストリームの基本的なことは下記の記事にもまとめていますので、そちらもご参照ください。

final BaseStream<String, Stream<String>> stream = Stream.of("aaa", "bbb", "ccc");
System.out.println("isParallel : " + stream.isParallel());

System.out.println("-- forEachRemaining --");
stream.iterator().forEachRemaining(value -> {
    System.out.println(value);
});

// 結果
// ↓
//isParallel : false
//-- forEachRemaining --
//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 BaseStream<String, Stream<String>> stream = Files.lines(path)) {

    System.out.println("-- forEachRemaining --");
    stream.iterator().forEachRemaining(value -> {
        System.out.println(value);
    });
}

// 結果
// ↓
//-- forEachRemaining --
//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 BaseStream<String, Stream<String>> stream = Files.lines(path);
try {
    System.out.println("-- forEachRemaining --");
    stream.iterator().forEachRemaining(value -> {
        System.out.println(value);
    });
} finally {
    stream.close();
}

// 結果
// ↓
//-- forEachRemaining --
//aaa
//bbb

boolean isParallel ()

終端操作が実行された場合にこのストリームが並列実行されるかどうかを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");
System.out.println(stream.isParallel()); // false

final var list = stream.peek(s -> {
    final var id = Thread.currentThread().threadId();
    System.out.println(s + " : " + "thread id = " + id);
}).toList();

System.out.println("list : " + list);

// 結果
// ↓
//aaa : thread id = 1
//bbb : thread id = 1
//ccc : thread id = 1
//list : [aaa, bbb, ccc]
final var stream = Stream.of("aaa", "bbb", "ccc").parallel();
System.out.println(stream.isParallel()); // true

final var list = stream.peek(s -> {
    final var id = Thread.currentThread().threadId();
    System.out.println(s + " : " + "thread id = " + id);
}).toList();

System.out.println("list : " + list);

// 結果
// ↓
//ccc : thread id = 1
//bbb : thread id = 1
//aaa : thread id = 32
//list : [aaa, bbb, ccc]

Iterator<T> iterator ()

このストリームの要素のイテレータを返します。

final BaseStream<String, Stream<String>> stream = Stream.of("aaa", "bbb", "ccc");

System.out.println("-- forEachRemaining --");
stream.iterator().forEachRemaining(value -> {
    System.out.println(value);
});

// 結果
// ↓
//-- forEachRemaining --
//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
        """);

try (final var lines = Files.lines(path).onClose(() -> {
    System.out.println("onClose is called!");
})) {
    System.out.println("-- forEach --");
    lines.forEach(System.out::println);
}

// 結果
// ↓
//-- forEach --
//aaa
//bbb
//onClose is called!
final var path = Path.of("R:", "java-work", "aaa.txt");
System.out.println(path); // R:\java-work\aaa.txt

try (final var lines = Files.lines(path)
        .onClose(() -> System.out.println("onClose 1"))
        .onClose(() -> System.out.println("onClose 2"))
        .onClose(() -> System.out.println("onClose 3"))
) {
    System.out.println("-- forEach --");
    lines.forEach(System.out::println);
}

// 結果
// ↓
//-- forEach --
//aaa
//bbb
//onClose 1
//onClose 2
//onClose 3

S parallel ()

同等の並列ストリームを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");
System.out.println(stream.isParallel()); // false

final var parallelStream = stream.parallel();
System.out.println(parallelStream.isParallel()); // true

final var list = parallelStream.peek(s -> {
    final var id = Thread.currentThread().threadId();
    System.out.println(s + " : " + "thread id = " + id);
}).toList();

System.out.println("list : " + list);

// 結果
// ↓
//aaa : thread id = 32
//ccc : thread id = 1
//bbb : thread id = 33
//list : [aaa, bbb, ccc]

S sequential ()

同等の順次ストリームを返します。

final var parallelStream = Stream.of("aaa", "bbb", "ccc").parallel();
System.out.println(parallelStream.isParallel()); // true

final var sequentialStream = parallelStream.sequential();
System.out.println(sequentialStream.isParallel()); // false

final var list = sequentialStream.peek(s -> {
    final var id = Thread.currentThread().threadId();
    System.out.println(s + " : " + "thread id = " + id);
}).toList();

System.out.println("list : " + list);

// 結果
// ↓
//aaa : thread id = 1
//bbb : thread id = 1
//ccc : thread id = 1
//list : [aaa, bbb, ccc]

Spliterator<T> spliterator ()

このストリームの要素のスプリッテレータを返します。

final BaseStream<String, Stream<String>> stream = Stream.of("aaa", "bbb", "ccc");
final var spliterator = stream.spliterator();

System.out.println("-- forEachRemaining --");
spliterator.forEachRemaining(value -> {
    System.out.println(value);
});

// 結果
// ↓
//-- forEachRemaining --
//aaa
//bbb
//ccc

S unordered ()

同等の順序付けされていないストリームを返します。

unordered で順序付けを解除すると、ステートフルな操作( distinct や sorted など) が効率よくなることがあります。

※処理時間は実行する環境によって変わります。

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();

    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) + " sec."); // 2.6085375 sec.
}

// unordered を使わない例
{
    final var start = System.nanoTime();

    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) + " sec."); // 3.4048646 sec.
}

関連記事

ページの先頭へ