CUBは子供の白熊

Java SE 8 実践プログラミングの練習問題を解く

第2章 ストリーム API の使い方 : 問題 7 : この Stream は有限か?

問題 7

上司に、Streamが有限かどうかを調べる

public static <T> boolean isFinite(Stream<T> stream)

メソッドを作成するように要請された。
このメソッドを実装せよ

解答

まず、メソッドのコードは以下のようになる。

public static <T> boolean isFinite(Stream<T> stream) {
    long size = stream.spliterator().getExactSizeIfKnown();
    return (0 <= size && size < Long.MAX_VALUE);
}

このメソッドを呼び出して、検証してみる。

// 単語リスト(有限)のケース
List<String> words = ~;
Stream<String> finiteStream = words.stream();
System.out.println(isFinite(finiteStream) ? "有限個": "無限個");
// 無限数列のケース
Stream<BigInteger> infiniteStream =
    Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
System.out.println(isFinite(infiniteStream) ? "有限個": "無限個");

さらに問題

上司の考えは良い考えか?

解答

良くない。
有限かどうかの判定のために終端操作(spliterator()メソッド)を使っている。
このメソッドを呼んだ後はストリームがクローズしていて、使用できない。

// 単語リスト(有限)のケース
List<String> words = ~;
Stream<String> finiteStream = words.stream();
System.out.println(isFinite(finiteStream) ? "有限個": "無限個");
System.out.println("個数 : " + finiteStream.count());  // IllegalStateException 発生

つまり、有限かどうかを判定するだけで終わってしまい、役に立たない。