広告

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 秒
}

関連記事

ページの先頭へ