CUBは子供の白熊

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

第8章 その他の Java 8 機能を理解する : 問題 9 : Scanner から Stream を生成

問題

Scannerを、単語, 行, 整数, または double のStreamに変換するメソッドを書け。

解答

以下の手順でStreamを生成する。

  1. ScannerからIteratorを生成
  2. IteratorからSpliteratorを得る
  3. SpliteratorからStreamを生成

まず、IteratorからStreamを生成するメソッドを定義する。

private static <T> Stream<T> createStream(Iterator<T> iterator) {
    Spliterator<T> spliterator = 
        Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED);
    return StreamSupport.stream(spliterator, false);
}

■ 単語のStream

public static Stream<String> wordStream(Scanner scanner) {
    return createStream(scanner);
}

■ 行のStream

public static Stream<String> lineStream(Scanner scanner) {
    Iterator<String> iterator = new Iterator<String>() {
        public String next() {
            return scanner.nextLine();
        }
        public boolean hasNext() {
            return scanner.hasNextLine();
        }
    };
    return createStream(iterator);
}

■ 整数のStream

public static IntStream intStream(Scanner scanner) {
    Iterator<Integer> iterator = new Iterator<Integer>() {
        public Integer next() {
            return scanner.nextInt();
        }
        public boolean hasNext() {
            return scanner.hasNextInt();
        }
    };
    return createStream(iterator).mapToInt(Integer::intValue);
}

■ double のStream

public static DoubleStream doubleStream(Scanner scanner) {
    Iterator<Double> iterator = new Iterator<Double>() {
        public Double next() {
            return scanner.nextDouble();
        }
        public boolean hasNext() {
            return scanner.hasNextDouble();
        }
    };
    return createStream(iterator).mapToDouble(Double::doubleValue);
}