Java8 Stream API ストリーム生成

java8 Stream APIでのストリーム生成についてのメモです。

java8で一番の大きな仕様追加となったラムダ式とStream APIです。
ラムダ式についてはこの前書いたので、Stream APIについて書こうと思います。

java8で追加されたStream APIではイテレーション処理で、流れるように処理を記述できます。
生成したストリームに対して、メソッドチェーンで処理を記述できます。
メソッドチェーンでは、ストリーム生成⇒中間処理⇒終端処理という形で処理を記述していきますが、
ストリーム生成の部分について書こうと思います。

Java SE 8のストリームを使用したデータ処理、パート1


目次

ストリーム生成

Stream APIを利用するためには、ストリームを生成する必要があります。
ストリームの生成方法はたくさんあるのでまとめてみました。

ofによるストリーム生成

一番簡単なのはofによるストリーム生成です。
of()にストリームの要素を列挙します。

String要素のストリームを生成する場合、of()にString要素を列挙します。
Stream<>に対応する型引数を指定します。

    // StringのStream
    Stream<String> strStream = Stream.of("aaa", "bbb", "ccc");
    strStream.forEach(System.out::println);

結果。

    aaa
    bbb
    ccc

intの要素のストリームを生成する場合も同様に列挙します。
int用にIntStreamというインターフェースがあるので、これを指定します。

    // IntStream
    IntStream intStream = IntStream.of(100, 200, 300);
    intStream.forEach(System.out::println);

結果。

    100
    200
    300

longの要素のストリームを生成する場合も同様に列挙します。
long用にLongStreamというインターフェースがあるので、これを指定します。

    // LongStream
    LongStream longStream = LongStream.of(10L, 20L, 30L);
    longStream.forEach(System.out::println);

結果。

    10
    20
    30

doubleの要素のストリームを生成する場合も同様に列挙します。
double用にDoubleStreamというインターフェースがあるので、これを指定します。

    // DoubleStream
    DoubleStream doubleStream = DoubleStream.of(1.0, 2.0, 3.0);
    doubleStream.forEach(System.out::println);

結果。

    1.0
    2.0
    3.0

配列の要素からストリームを生成する場合、of()で配列を指定します。

    // 配列からのStream
    String[] array = {"AAA", "BBB", "CCC"};
    Stream<String> streamArray = Stream.of(array);
    streamArray.forEach(System.out::println);

結果

    AAA
    BBB
    CCC

テストコード

public void ofによるストリーム生成() {
    // StringのStream
    Stream<String> strStream = Stream.of("aaa", "bbb", "ccc");
    strStream.forEach(System.out::println);

    Stream<String> strStream2 = Stream.of("aaa", "bbb", "ccc");
    List<String> list = strStream2.collect(Collectors.toList());
    assertThat(list).containsOnly("aaa", "bbb", "ccc");

    // IntStream
    IntStream intStream = IntStream.of(100, 200, 300);
    intStream.forEach(System.out::println);

    IntStream intStream2 = IntStream.of(100, 200, 300);
    List<Integer> intList = intStream2.boxed().collect(Collectors.toList());
    assertThat(intList).containsOnly(100, 200, 300);

    // LongStream
    LongStream longStream = LongStream.of(10L, 20L, 30L);
    longStream.forEach(System.out::println);

    LongStream longStream2 = LongStream.of(10L, 20L, 30L);
    List<Long> longList = longStream2.boxed().collect(Collectors.toList());
    assertThat(longList).containsOnly(10L, 20L, 30L);

    // DoubleStream
    DoubleStream doubleStream = DoubleStream.of(1.0, 2.0, 3.0);
    doubleStream.forEach(System.out::println);

    DoubleStream doubleStream2 = DoubleStream.of(1.0, 2.0, 3.0);
    List<Double> doubleList = doubleStream2.boxed().collect(Collectors.toList());
    assertThat(doubleList).containsOnly(1.0, 2.0, 3.0);

    // 配列からのStream
    String[] array = {"AAA", "BBB", "CCC"};
    Stream<String> streamArray = Stream.of(array);
    streamArray.forEach(System.out::println);

    Stream<String> streamArray2 = Stream.of(array);
    List<String> listFromArray = streamArray2.collect(Collectors.toList());
    assertThat(listFromArray).containsOnly("AAA", "BBB", "CCC");
}

リストからのストリーム生成

リストからストリームを生成する場合、Collectionインターフェースのstream()を使います。

Stringのリストからのストリーム生成の場合。

    // Stringのリスト
    List<String> list = Arrays.asList("aaa", "bbb", "ccc");
    Stream<String> StrStream = list.stream();
    StrStream.forEach(System.out::println);

結果。

    aaa
    bbb
    ccc

intのリストからのストリーム生成の場合。

    // Integerのリスト
    List<Integer> intList = Arrays.asList(1, 2, 3);
    Stream<Integer> intStream = intList.stream();
    intStream.forEach(System.out::println);

結果。

    1
    2
    3

テストコード。

@Test
public void リストからのストリーム処理() {
    // Stringのリスト
    List<String> list = Arrays.asList("aaa", "bbb", "ccc");
    Stream<String> StrStream = list.stream();
    StrStream.forEach(System.out::println);

    Stream<String> strStream2 = list.stream();
    List<String> listFromStream = strStream2.collect(Collectors.toList());
    assertThat(listFromStream).containsOnly("aaa", "bbb", "ccc");

    // Integerのリスト
    List<Integer> intList = Arrays.asList(1, 2, 3);
    Stream<Integer> intStream = intList.stream();
    intStream.forEach(System.out::println);

    Stream<Integer> intStream2 = intList.stream();
    List<Integer> intListFromStream = intStream2.collect(Collectors.toList());
    assertThat(intListFromStream).containsOnly(1, 2, 3);
}

配列からのストリーム生成

配列からストリームを生成する場合、Arrays.stream()で配列を指定します。

Stringの配列の場合。

    // Stringの配列
    String[] array = {"aaa", "bbb", "ccc", "eee", "fff"};
    Stream<String> stream = Arrays.stream(array);
    stream.forEach(System.out::println);

結果

    aaa
    bbb
    ccc
    eee
    fff

Arrays.stream()ではストリームの対象となる要素を指定できます。
第2引数にストリーム対象となる最初のインデックスを指定し、
第3引数にストリーム対象となる最後のインデックスの直後のインデックスを指定します。

    // Stringの配列(index指定)
    Stream<String> streamWithIndex = Arrays.stream(array, 2, 4);
    streamWithIndex.forEach(System.out::println);

結果

    ccc
    eee

intの配列の場合。

    // intの配列
    int[] intArray = {100, 200, 300, 400, 500};
    IntStream intStream = Arrays.stream(intArray);
    intStream.forEach(System.out::println);

結果

    100
    200
    300
    400
    500

longの配列の場合。

    // longの配列
    long[] longArray = {10L, 20L, 30L};
    LongStream longStream = Arrays.stream(longArray);
    longStream.forEach(System.out::println);

結果

    10
    20
    30

doubleの配列の場合。

    // doubleの配列
    double[] doubleArray = {1.0, 2.0, 3.0};
    DoubleStream doubleStream = Arrays.stream(doubleArray);
    doubleStream.forEach(System.out::println);

結果

    1.0
    2.0
    3.0

テストコード

@Test
public void 配列からのストリーム処理() {
    // Stringの配列
    String[] array = {"aaa", "bbb", "ccc", "eee", "fff"};
    Stream<String> stream = Arrays.stream(array);
    stream.forEach(System.out::println);

    Stream<String> stream2 = Arrays.stream(array);
    String[] arrayFromStream = stream2.toArray(String[]::new);
    assertThat(arrayFromStream).containsOnly("aaa", "bbb", "ccc", "eee", "fff");

    // Stringの配列(index指定)
    Stream<String> streamWithIndex = Arrays.stream(array, 2, 4);
    streamWithIndex.forEach(System.out::println);

    Stream<String> streamWithIndex2 = Arrays.stream(array, 2, 4);
    String[] arrayWithIndex = streamWithIndex2.toArray(String[]::new);
    assertThat(arrayWithIndex).containsOnly("ccc", "eee");

    // intの配列
    int[] intArray = {100, 200, 300, 400, 500};
    IntStream intStream = Arrays.stream(intArray);
    intStream.forEach(System.out::println);

    IntStream intStream2 = Arrays.stream(intArray);
    int[] intArrayFromStream = intStream2.toArray();
    assertThat(intArrayFromStream).containsOnly(100, 200, 300, 400, 500);

    // longの配列
    long[] longArray = {10L, 20L, 30L};
    LongStream longStream = Arrays.stream(longArray);
    longStream.forEach(System.out::println);

    LongStream longStream2 = Arrays.stream(longArray);
    long[] longArrayFromStream = longStream2.toArray();
    assertThat(longArrayFromStream).containsOnly(10L, 20L, 30L);

    // doubleの配列
    double[] doubleArray = {1.0, 2.0, 3.0};
    DoubleStream doubleStream = Arrays.stream(doubleArray);
    doubleStream.forEach(System.out::println);

    DoubleStream doubleStream2 = Arrays.stream(doubleArray);
    double[] doubleArrayFromStream = doubleStream2.toArray();
    assertThat(doubleArrayFromStream).containsOnly(1.0, 2.0, 3.0);
}

rangeによるストリーム生成

range()では引数で指定した範囲で、連続した値のストリームを生成します。
第1引数から第2引数(を含まない)までの範囲のストリームを生成します。

intの場合。

    // IntStream
    IntStream.range(0, 10).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

longの場合。

    // LongStream
    LongStream.range(0L, 10L).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

DoubleStreamにはrangeメソッドはありません。

    // error!!
    // DoubleStream.range(0.0, 10.0);

テストコード

@Test
public void rangeによるストリーム生成() {
    // IntStream
    IntStream.range(0, 10).forEach(System.out::println);

    IntStream intStream = IntStream.range(0, 10);
    List<Integer> intList = intStream.boxed().collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

    // LongStream
    LongStream.range(0L, 10L).forEach(System.out::println);

    LongStream longStream = LongStream.range(0L, 10L);
    List<Long> longList = longStream.boxed().collect(Collectors.toList());
    assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L);

    // error!!
    // DoubleStream.range(0.0, 10.0);
}

rangeClosedによるストリーム生成

rangeClosed()ではrange()同様に、引数で指定した範囲で連続した値のストリームを生成します。
range()との違いは、第2引数で指定した範囲を含む点です。

intの場合。

    // IntStream
    IntStream.rangeClosed(0, 10).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

longの場合。

    // LongStream
    LongStream.rangeClosed(0L, 10L).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

DoubleStreamにはrangeClosedメソッドはありません。

    // error!!
    // DoubleStream.rangeClosed(0.0, 10.0);

テストコード

@Test
public void rangeClosedによるストリーム生成() {
    // IntStream
    IntStream.rangeClosed(0, 10).forEach(System.out::println);

    IntStream intStream = IntStream.rangeClosed(0, 10);
    List<Integer> intList = intStream.boxed().collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    // LongStream
    LongStream.rangeClosed(0L, 10L).forEach(System.out::println);

    LongStream longStream = LongStream.rangeClosed(0L, 10L);
    List<Long> longList = longStream.boxed().collect(Collectors.toList());
    assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);

    // error!!
    // DoubleStream.rangeClosed(0.0, 10.0);
}

iterateによるストリーム生成

iterate()では第1引数で初期要素を指定して、第2引数で指定した関数を適用した要素のストリームを生成します。
ただし、そのままでは無限に生成するため、limit()メソッドで繰り返す回数を指定します。

intの場合。
第2引数はIntUnaryOperatorになっているので、intを引数に取ってintを返す関数を記述します。

    // IntStream
    IntStream.iterate(0, i -> i + 100)
            .limit(10)
            .forEach(System.out::println);

結果

    0
    100
    200
    300
    400
    500
    600
    700
    800
    900

longの場合。
第2引数はLongUnaryOperatorになっているので、longを引数に取ってlongを返す関数を記述します。

    LongStream.iterate(0L, i -> i + 10)
            .limit(5)
            .forEach(System.out::println);

結果

    0
    10
    20
    30
    40

doubleの場合。
第2引数はDoubleUnaryOperatorになっているので、doubleを引数に取ってdoubleを返す関数を記述します。

    DoubleStream.iterate(0.0, i -> i + 1.0)
            .limit(5)
            .forEach(System.out::println);

結果

    0.0
    1.0
    2.0
    3.0
    4.0

Stringの場合。
第2引数はUnaryOperatorになっているので、引数に取った型を返す関数を記述します。

    Stream.iterate("a", s -> "[" + s + "]")
            .limit(5)
            .forEach(System.out::println);

結果

    a
    [a]
    [[a]]
    [[[a]]]
    [[[[a]]]]

テストコード

@Test
public void iterateによるストリーム生成() {
    // IntStream
    IntStream.iterate(0, i -> i + 100)
            .limit(10)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.iterate(0, i -> i + 100)
            .limit(10)
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 100, 200, 300, 400, 500, 600, 700, 800, 900);

    // LongStream
    LongStream.iterate(0L, i -> i + 10)
            .limit(5)
            .forEach(System.out::println);

    List<Long> longList = LongStream.iterate(0L, i -> i + 10)
            .limit(5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(longList).containsOnly(0L, 10L, 20L, 30L, 40L);

    // DoubleStream
    DoubleStream.iterate(0.0, i -> i + 1.0)
            .limit(5)
            .forEach(System.out::println);

    List<Double> doubleList = DoubleStream.iterate(0.0, i -> i + 1.0)
            .limit(5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(doubleList).containsOnly(0.0, 1.0, 2.0, 3.0, 4.0);

    // Stream
    Stream.iterate("a", s -> "[" + s + "]")
            .limit(5)
            .forEach(System.out::println);

    List<String> strList = Stream.iterate("a", s -> "[" + s + "]")
            .limit(5)
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("a", "[a]", "[[a]]", "[[[a]]]", "[[[[a]]]]");
}

generateによるストリーム生成

generate()では引数で指定した関数で生成された要素のストリームを生成します。
iterate同様、そのままでは無限に生成するため、limit()メソッドで繰り返す回数を指定します。

Stringの場合。
引数はSupplierになっているので、引数を取らず値を返す関数を記述します。

    // Stream
    Stream.generate(() -> "abc")
            .limit(5)
            .forEach(System.out::println);

結果

    abc
    abc
    abc
    abc
    abc

intの場合。
引数はIntSupplierになっているので、引数を取らずintを返す関数を記述します。

    // IntStream
    IntStream.generate(() -> 123)
            .limit(5)
            .forEach(System.out::println);

結果

    123
    123
    123
    123
    123

longの場合。
引数はLongSupplierになっているので、引数を取らずlongを返す関数を記述します。

    // LongStream
    LongStream.generate(() -> 10L)
            .limit(5)
            .forEach(System.out::println);

結果

    10
    10
    10
    10
    10

doubleの場合。
引数はDoubleSupplierになっているので、引数を取らずdoubleを返す関数を記述します。

    // DoubleStream
    DoubleStream.generate(() -> 10.0)
            .limit(5)
            .forEach(System.out::println);

結果

    10.0
    10.0
    10.0
    10.0
    10.0

テストコード

@Test
public void generateによるストリーム生成() {
    // Stream
    Stream.generate(() -> "abc")
            .limit(5)
            .forEach(System.out::println);

    List<String> strList = Stream.generate(() -> "abc")
            .limit(5)
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("abc", "abc", "abc", "abc", "abc");

    // IntStream
    IntStream.generate(() -> 123)
            .limit(5)
            .forEach(System.out::println);

    List<Integer> intList = IntStream.generate(() -> 123)
            .limit(5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(123, 123, 123, 123, 123);

    // LongStream
    LongStream.generate(() -> 10L)
            .limit(5)
            .forEach(System.out::println);

    List<Long> longList = LongStream.generate(() -> 10L)
            .limit(5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(longList).containsOnly(10L, 10L, 10L, 10L, 10L);

    // DoubleStream
    DoubleStream.generate(() -> 10.0)
            .limit(5)
            .forEach(System.out::println);

    List<Double> doubleList = DoubleStream.generate(() -> 10.0)
            .limit(5)
            .boxed()
            .collect(Collectors.toList());
    assertThat(doubleList).containsOnly(10.0, 10.0, 10.0, 10.0, 10.0);
}

concatによるストリーム生成

concat()では引数で指定した2つのストリームを合成したストリームを生成します。

Stringの場合。

    // Stream
    Stream<String> stream1 = Stream.of("a", "b", "c", "d", "e");
    Stream<String> stream2 = Stream.of("A", "B", "C", "D", "E");
    Stream.concat(stream1, stream2).forEach(System.out::println);

結果

    a
    b
    c
    d
    e
    A
    B
    C
    D
    E

intの場合。

    // IntStream
    IntStream intStream1 = IntStream.range(0, 5);
    IntStream intStream2 = IntStream.range(5, 10);
    IntStream.concat(intStream1, intStream2).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

longの場合

    // LongStream
    LongStream longStream1  = LongStream.range(0L, 5L);
    LongStream longStream2  = LongStream.range(5L, 10L);
    LongStream.concat(longStream1, longStream2).forEach(System.out::println);

結果

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9

doubleの場合。

    // DoubleStream
    DoubleStream doubleStream1 = DoubleStream.of(0.0, 1.0, 2.0);
    DoubleStream doubleStream2 = DoubleStream.of(3.0, 4.0, 5.0);
    DoubleStream.concat(doubleStream1, doubleStream2).forEach(System.out::println);

結果

    0.0
    1.0
    2.0
    3.0
    4.0
    5.0

テストコード

@Test
public void concatによるストリーム生成() {
    // Stream
    Stream<String> stream1 = Stream.of("a", "b", "c", "d", "e");
    Stream<String> stream2 = Stream.of("A", "B", "C", "D", "E");
    Stream.concat(stream1, stream2).forEach(System.out::println);

    List<String> strList = Stream.concat(Stream.of("a", "b", "c", "d", "e"),
            Stream.of("A", "B", "C", "D", "E"))
            .collect(Collectors.toList());
    assertThat(strList).containsOnly("a", "b", "c", "d", "e", "A", "B", "C", "D", "E");

    // IntStream
    IntStream intStream1 = IntStream.range(0, 5);
    IntStream intStream2 = IntStream.range(5, 10);
    IntStream.concat(intStream1, intStream2).forEach(System.out::println);

    List<Integer> intList = IntStream.concat(IntStream.range(0, 5), IntStream.range(5, 10))
            .boxed()
            .collect(Collectors.toList());
    assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

    // LongStream
    LongStream longStream1  = LongStream.range(0L, 5L);
    LongStream longStream2  = LongStream.range(5L, 10L);
    LongStream.concat(longStream1, longStream2).forEach(System.out::println);

    List<Long> longList = LongStream.concat(LongStream.range(0L, 5L), LongStream.range(5L, 10L))
            .boxed()
            .collect(Collectors.toList());
    assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L);

    // DoubleStream
    DoubleStream doubleStream1 = DoubleStream.of(0.0, 1.0, 2.0);
    DoubleStream doubleStream2 = DoubleStream.of(3.0, 4.0, 5.0);
    DoubleStream.concat(doubleStream1, doubleStream2).forEach(System.out::println);

    List<Double> doubleList = DoubleStream.concat(DoubleStream.of(0.0, 1.0, 2.0),
            DoubleStream.of(3.0, 4.0, 5.0))
            .boxed()
            .collect(Collectors.toList());
    assertThat(doubleList).containsOnly(0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
}

charsからのストリーム生成

chars()では文字列からchar値のIntStreamを生成します。
サロゲートペアは考慮されません。

生成されたストリームをintとcharで出力。

    // chars
    String str = "abcde1234あいう";
    str.chars()
            .forEach(System.out::println);
    str.chars()
            .forEach(c -> System.out.println((char)c));

結果

    97
    98
    99
    100
    101
    49
    50
    51
    52
    12354
    12356
    12358
    a
    b
    c
    d
    e
    1
    2
    3
    4
    あ
    い
    う

テストコード

@Test
public void charsからのストリーム生成() {
    // chars
    String str = "abcde1234あいう";
    str.chars()
            .forEach(System.out::println);
    str.chars()
            .forEach(c -> System.out.println((char)c));

    int[] charArray = str.chars()
            .toArray();
    assertThat(charArray).containsOnly(97, 98, 99, 100, 101,
            49, 50, 51, 52,
            12354, 12356, 12358);
}

codePointsからのストリーム生成

codePoints()ではUnicodeのコードポイント値をIntStreamで生成します。

smileの絵文字(UTF-16で0xD83D 0xDE04)からストリームを生成してみます。
Unicode Character 'SMILING FACE WITH OPEN MOUTH AND SMILING EYES' (U+1F604)

コードポイントをintと16進数で表示してみます。

    // codePoints
    String emoji = "\uD83D\uDE04";
    emoji.codePoints()
            .forEach(System.out::println);
    emoji.codePoints()
            .mapToObj(Integer::toHexString)
            .forEach(System.out::print);

結果

    128516
    1f604

テストコード

@Test
public void codePointsからのストリーム生成() {
    // codePoints
    String emoji = "\uD83D\uDE04";
    emoji.codePoints()
            .forEach(System.out::println);
    emoji.codePoints()
            .mapToObj(Integer::toHexString)
            .forEach(System.out::print);

    int[] emojiInt = emoji.codePoints().toArray();
    assertThat(emojiInt).containsOnly(128516);
}

Randomからのストリーム生成

Randomからも乱数のストリームを生成できます。

ints()でIntStreamが生成できます。
第1引数で生成する要素の数、第2引数と第3引数で生成される乱数の範囲を指定します。

    // ints
    Random intRandom = new Random(100);
    intRandom.ints(5, 1, 1000).forEach(System.out::println);

結果

    971
    506
    2
    703
    440

longs()でLongStreamが生成できます。
第1引数で生成する要素の数、第2引数と第3引数で生成される乱数の範囲を指定します。

    // longs
    Random longRandom = new Random(100);
    longRandom.longs(5, 1, 1000).forEach(System.out::println);

結果

    910
    266
    97
    677
    955

doubles()でDoubleStreamが生成できます。
第1引数で生成する要素の数、第2引数と第3引数で生成される乱数の範囲を指定します。

    // doubles
    Random doubleRandom = new Random(100);
    doubleRandom.doubles(5, 1, 1000).forEach(System.out::println);

結果

    722.2876452047838
    195.78108129035746
    667.4924130812963
    778.6624265427389
    618.9889984180408

テストコード

@Test
public void Randomからのストリーム生成() {
    // ints
    Random intRandom = new Random(100);
    intRandom.ints(5, 1, 1000).forEach(System.out::println);

    List<Integer> list = intRandom.ints(5, 1, 1000)
            .boxed()
            .collect(Collectors.toList());
    assertThat(list).containsOnly(850, 399, 777, 503, 830);

    // longs
    Random longRandom = new Random(100);
    longRandom.longs(5, 1, 1000).forEach(System.out::println);

    List<Long> longList = longRandom.longs(5, 1, 1000)
            .boxed()
            .collect(Collectors.toList());
    assertThat(longList).containsOnly(36L, 55L, 415L, 942L, 722L);

    // doubles
    Random doubleRandom = new Random(100);
    doubleRandom.doubles(5, 1, 1000).forEach(System.out::println);

    List<Integer> doubleList = doubleRandom.doubles(5, 1, 1000)
            .boxed()
            .mapToInt(Double::intValue)
            .boxed()
            .collect(Collectors.toList());
    assertThat(doubleList).containsOnly(623, 237, 487, 680, 525);
}

emptyによるストリーム生成

empty()で空のストリームを生成できます。
Stream, IntStream, LongStream, DoubleStreamでそれぞれ生成できます。

    Stream.empty().forEach(System.out::println);
    IntStream.empty().forEach(System.out::println);
    LongStream.empty().forEach(System.out::println);
    DoubleStream.empty().forEach(System.out::println);

出力結果は空。

    出力なし

テストコード

@Test
public void emptyによるストリーム生成() {
    Stream.empty().forEach(System.out::println);
    IntStream.empty().forEach(System.out::println);
    LongStream.empty().forEach(System.out::println);
    DoubleStream.empty().forEach(System.out::println);

    IntStream stream = IntStream.empty();
    List<Integer> list = stream.boxed().map(i -> i + 1).collect(Collectors.toList());
    assertThat(list).isEmpty();
}

ファイル読み込みからのストリーム生成

ファイル読み込みではBufferReader.lines()またはFiles.lines()で
Stringのストリームを生成できます。

下記のテキストファイルを用意します。

memo.txt

aiueo
かきくけこ

BufferReaderでファイルを読み込み、ストリームを生成して、中身を出力してみます。

    // BufferReader
    try(BufferedReader reader = new BufferedReader(new FileReader("src/main/java/text/memo.txt"))) {
        Stream<String> stream = reader.lines();
        stream.forEach(System.out::println);
    } catch (IOException e) {
        throw e;
    }

結果

    aiueo
    かきくけこ

同じファイルをFilesで読み込み、ストリームを生成して、中身を出力してみます。

    // Files
    Path path = Paths.get("src/main/java/text/memo.txt");
    try(Stream<String> stream = Files.lines(path)) {
        stream.forEach(System.out::println);
    } catch (IOException e) {
        throw e;
    }

結果

    aiueo
    かきくけこ

テストコード

@Test
public void ファイル読み込みからのストリーム生成() throws IOException {
    // BufferReader
    try(BufferedReader reader = new BufferedReader(new FileReader("src/main/java/text/memo.txt"))) {
        Stream<String> stream = reader.lines();
        stream.forEach(System.out::println);
    } catch (IOException e) {
        throw e;
    }

    try(BufferedReader reader = new BufferedReader(new FileReader("src/main/java/text/memo.txt"))) {
        Stream<String> stream2 = reader.lines();
        List<String> list = stream2.collect(Collectors.toList());
        assertThat(list).containsOnly("aiueo", "かきくけこ");
    } catch (IOException e) {
        throw e;
    }

    // Files
    Path path = Paths.get("src/main/java/text/memo.txt");
    try(Stream<String> stream = Files.lines(path)) {
        stream.forEach(System.out::println);
    } catch (IOException e) {
        throw e;
    }

    try(Stream<String> stream = Files.lines(path)) {
        List<String> list = stream.collect(Collectors.toList());
        assertThat(list).containsOnly("aiueo", "かきくけこ");
    } catch (IOException e) {
        throw e;
    }
}

ディレクトリ読み込みからのストリーム生成

ディレクトリの読み込みでは、Filesでディレクトリのファイルを走査できます。
Files.find()、Files.list()、Files.walk()でPathを要素とするストリームを生成できます。

下記の様なディレクトリ構成の場合。

--text/
  ├-memo.txt
  ├-access.log
  └-csv/
     └data.csv

Files.find()ではディレクトリを検索して、検索条件に一致したPathのストリームを生成します。
第1引数に検索対象のルートパス、第2引数に検索するディレクトリの深さ、
第3引数にBiPredicateの関数を与えます。
BiPredicateは引数としてPathとBasicFileAttributesを取ります。

    Path path = Paths.get("src/main/java/text");

    // find
    try {
        Files.find(path, 2, (p, attr) -> p.toString().endsWith("txt"))
                .forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

結果

    src\main\java\text\memo.txt

Files.list()では指定したパスのディレクトリ内の要素のPathのストリームを生成します。
ディレクトリは対象外になります。

    Path path = Paths.get("src/main/java/text");

    // list
    try {
        Files.list(path).forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

結果

    src\main\java\text\access.log
    src\main\java\text\csv
    src\main\java\text\memo.txt

Files.walk()はlist()と同様ですが、子ディレクトリも走査します。

    Path path = Paths.get("src/main/java/text");

    // walk
    try {
        Files.walk(path).forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

結果

    src\main\java\text
    src\main\java\text\access.log
    src\main\java\text\csv
    src\main\java\text\csv\data.csv
    src\main\java\text\memo.txt

テストコード

@Test
public void ディレクトリ読み込みからのストリーム生成() {
    Path path = Paths.get("src/main/java/text");

    // find
    try {
        Files.find(path, 2, (p, attr) -> p.toString().endsWith("txt"))
                .forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        List<String> list =
                Files.find(path, 2, (p, attr) -> p.toString().endsWith("txt"))
                        .map(Path::toString)
                        .collect(Collectors.toList());
        assertThat(list).containsOnly("src\\main\\java\\text\\memo.txt");
    } catch (IOException e) {
        e.printStackTrace();
    }

    // list
    try {
        Files.list(path).forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        List<String> list =
                Files.list(path)
                        .map(Path::toString)
                        .collect(Collectors.toList());
        assertThat(list).containsOnly("src\\main\\java\\text\\memo.txt",
                "src\\main\\java\\text\\access.log",
                "src\\main\\java\\text\\csv");
    } catch (IOException e) {
        e.printStackTrace();
    }

    // walk
    try {
        Files.walk(path).forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        List<String> list =
                Files.walk(path)
                        .map(Path::toString)
                        .collect(Collectors.toList());
        assertThat(list).containsOnly("src\\main\\java\\text",
                "src\\main\\java\\text\\memo.txt",
                "src\\main\\java\\text\\access.log",
                "src\\main\\java\\text\\csv",
                "src\\main\\java\\text\\csv\\data.csv");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

テストコード全体

今回のテストコード全体です。

CreateStreamTest.java

package javase8;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

public class CreateStreamTest {
    @Test
    public void ofによるストリーム生成() {
        // StringのStream
        Stream<String> strStream = Stream.of("aaa", "bbb", "ccc");
        strStream.forEach(System.out::println);

        Stream<String> strStream2 = Stream.of("aaa", "bbb", "ccc");
        List<String> list = strStream2.collect(Collectors.toList());
        assertThat(list).containsOnly("aaa", "bbb", "ccc");

        // IntStream
        IntStream intStream = IntStream.of(100, 200, 300);
        intStream.forEach(System.out::println);

        IntStream intStream2 = IntStream.of(100, 200, 300);
        List<Integer> intList = intStream2.boxed().collect(Collectors.toList());
        assertThat(intList).containsOnly(100, 200, 300);

        // LongStream
        LongStream longStream = LongStream.of(10L, 20L, 30L);
        longStream.forEach(System.out::println);

        LongStream longStream2 = LongStream.of(10L, 20L, 30L);
        List<Long> longList = longStream2.boxed().collect(Collectors.toList());
        assertThat(longList).containsOnly(10L, 20L, 30L);

        // DoubleStream
        DoubleStream doubleStream = DoubleStream.of(1.0, 2.0, 3.0);
        doubleStream.forEach(System.out::println);

        DoubleStream doubleStream2 = DoubleStream.of(1.0, 2.0, 3.0);
        List<Double> doubleList = doubleStream2.boxed().collect(Collectors.toList());
        assertThat(doubleList).containsOnly(1.0, 2.0, 3.0);

        // 配列からのStream
        String[] array = {"AAA", "BBB", "CCC"};
        Stream<String> streamArray = Stream.of(array);
        streamArray.forEach(System.out::println);

        Stream<String> streamArray2 = Stream.of(array);
        List<String> listFromArray = streamArray2.collect(Collectors.toList());
        assertThat(listFromArray).containsOnly("AAA", "BBB", "CCC");
    }

    @Test
    public void リストからのストリーム生成() {
        // Stringのリスト
        List<String> list = Arrays.asList("aaa", "bbb", "ccc");
        Stream<String> StrStream = list.stream();
        StrStream.forEach(System.out::println);

        Stream<String> strStream2 = list.stream();
        List<String> listFromStream = strStream2.collect(Collectors.toList());
        assertThat(listFromStream).containsOnly("aaa", "bbb", "ccc");

        // Integerのリスト
        List<Integer> intList = Arrays.asList(1, 2, 3);
        Stream<Integer> intStream = intList.stream();
        intStream.forEach(System.out::println);

        Stream<Integer> intStream2 = intList.stream();
        List<Integer> intListFromStream = intStream2.collect(Collectors.toList());
        assertThat(intListFromStream).containsOnly(1, 2, 3);
    }

    @Test
    public void 配列からのストリーム生成() {
        // Stringの配列
        String[] array = {"aaa", "bbb", "ccc", "eee", "fff"};
        Stream<String> stream = Arrays.stream(array);
        stream.forEach(System.out::println);

        Stream<String> stream2 = Arrays.stream(array);
        String[] arrayFromStream = stream2.toArray(String[]::new);
        assertThat(arrayFromStream).containsOnly("aaa", "bbb", "ccc", "eee", "fff");

        // Stringの配列(index指定)
        Stream<String> streamWithIndex = Arrays.stream(array, 2, 4);
        streamWithIndex.forEach(System.out::println);

        Stream<String> streamWithIndex2 = Arrays.stream(array, 2, 4);
        String[] arrayWithIndex = streamWithIndex2.toArray(String[]::new);
        assertThat(arrayWithIndex).containsOnly("ccc", "eee");

        // intの配列
        int[] intArray = {100, 200, 300, 400, 500};
        IntStream intStream = Arrays.stream(intArray);
        intStream.forEach(System.out::println);

        IntStream intStream2 = Arrays.stream(intArray);
        int[] intArrayFromStream = intStream2.toArray();
        assertThat(intArrayFromStream).containsOnly(100, 200, 300, 400, 500);

        // longの配列
        long[] longArray = {10L, 20L, 30L};
        LongStream longStream = Arrays.stream(longArray);
        longStream.forEach(System.out::println);

        LongStream longStream2 = Arrays.stream(longArray);
        long[] longArrayFromStream = longStream2.toArray();
        assertThat(longArrayFromStream).containsOnly(10L, 20L, 30L);

        // doubleの配列
        double[] doubleArray = {1.0, 2.0, 3.0};
        DoubleStream doubleStream = Arrays.stream(doubleArray);
        doubleStream.forEach(System.out::println);

        DoubleStream doubleStream2 = Arrays.stream(doubleArray);
        double[] doubleArrayFromStream = doubleStream2.toArray();
        assertThat(doubleArrayFromStream).containsOnly(1.0, 2.0, 3.0);
    }

    @Test
    public void rangeによるストリーム生成() {
        // IntStream
        IntStream.range(0, 10).forEach(System.out::println);

        IntStream intStream = IntStream.range(0, 10);
        List<Integer> intList = intStream.boxed().collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

        // LongStream
        LongStream.range(0L, 10L).forEach(System.out::println);

        LongStream longStream = LongStream.range(0L, 10L);
        List<Long> longList = longStream.boxed().collect(Collectors.toList());
        assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L);

        // error!!
        // DoubleStream.range(0.0, 10.0);
    }

    @Test
    public void rangeClosedによるストリーム生成() {
        // IntStream
        IntStream.rangeClosed(0, 10).forEach(System.out::println);

        IntStream intStream = IntStream.rangeClosed(0, 10);
        List<Integer> intList = intStream.boxed().collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // LongStream
        LongStream.rangeClosed(0L, 10L).forEach(System.out::println);

        LongStream longStream = LongStream.rangeClosed(0L, 10L);
        List<Long> longList = longStream.boxed().collect(Collectors.toList());
        assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);

        // error!!
        // DoubleStream.rangeClosed(0.0, 10.0);
    }

    @Test
    public void iterateによるストリーム生成() {
        // IntStream
        IntStream.iterate(0, i -> i + 100)
                .limit(10)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.iterate(0, i -> i + 100)
                .limit(10)
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 100, 200, 300, 400, 500, 600, 700, 800, 900);

        // LongStream
        LongStream.iterate(0L, i -> i + 10)
                .limit(5)
                .forEach(System.out::println);

        List<Long> longList = LongStream.iterate(0L, i -> i + 10)
                .limit(5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(longList).containsOnly(0L, 10L, 20L, 30L, 40L);

        // DoubleStream
        DoubleStream.iterate(0.0, i -> i + 1.0)
                .limit(5)
                .forEach(System.out::println);

        List<Double> doubleList = DoubleStream.iterate(0.0, i -> i + 1.0)
                .limit(5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(doubleList).containsOnly(0.0, 1.0, 2.0, 3.0, 4.0);

        // Stream
        Stream.iterate("a", s -> "[" + s + "]")
                .limit(5)
                .forEach(System.out::println);

        List<String> strList = Stream.iterate("a", s -> "[" + s + "]")
                .limit(5)
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("a", "[a]", "[[a]]", "[[[a]]]", "[[[[a]]]]");
    }

    @Test
    public void generateによるストリーム生成() {
        // Stream
        Stream.generate(() -> "abc")
                .limit(5)
                .forEach(System.out::println);

        List<String> strList = Stream.generate(() -> "abc")
                .limit(5)
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("abc", "abc", "abc", "abc", "abc");

        // IntStream
        IntStream.generate(() -> 123)
                .limit(5)
                .forEach(System.out::println);

        List<Integer> intList = IntStream.generate(() -> 123)
                .limit(5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(123, 123, 123, 123, 123);

        // LongStream
        LongStream.generate(() -> 10L)
                .limit(5)
                .forEach(System.out::println);

        List<Long> longList = LongStream.generate(() -> 10L)
                .limit(5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(longList).containsOnly(10L, 10L, 10L, 10L, 10L);

        // DoubleStream
        DoubleStream.generate(() -> 10.0)
                .limit(5)
                .forEach(System.out::println);

        List<Double> doubleList = DoubleStream.generate(() -> 10.0)
                .limit(5)
                .boxed()
                .collect(Collectors.toList());
        assertThat(doubleList).containsOnly(10.0, 10.0, 10.0, 10.0, 10.0);
    }

    @Test
    public void concatによるストリーム生成() {
        // Stream
        Stream<String> stream1 = Stream.of("a", "b", "c", "d", "e");
        Stream<String> stream2 = Stream.of("A", "B", "C", "D", "E");
        Stream.concat(stream1, stream2).forEach(System.out::println);

        List<String> strList = Stream.concat(Stream.of("a", "b", "c", "d", "e"),
                Stream.of("A", "B", "C", "D", "E"))
                .collect(Collectors.toList());
        assertThat(strList).containsOnly("a", "b", "c", "d", "e", "A", "B", "C", "D", "E");

        // IntStream
        IntStream intStream1 = IntStream.range(0, 5);
        IntStream intStream2 = IntStream.range(5, 10);
        IntStream.concat(intStream1, intStream2).forEach(System.out::println);

        List<Integer> intList = IntStream.concat(IntStream.range(0, 5), IntStream.range(5, 10))
                .boxed()
                .collect(Collectors.toList());
        assertThat(intList).containsOnly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

        // LongStream
        LongStream longStream1  = LongStream.range(0L, 5L);
        LongStream longStream2  = LongStream.range(5L, 10L);
        LongStream.concat(longStream1, longStream2).forEach(System.out::println);

        List<Long> longList = LongStream.concat(LongStream.range(0L, 5L), LongStream.range(5L, 10L))
                .boxed()
                .collect(Collectors.toList());
        assertThat(longList).containsOnly(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L);

        // DoubleStream
        DoubleStream doubleStream1 = DoubleStream.of(0.0, 1.0, 2.0);
        DoubleStream doubleStream2 = DoubleStream.of(3.0, 4.0, 5.0);
        DoubleStream.concat(doubleStream1, doubleStream2).forEach(System.out::println);

        List<Double> doubleList = DoubleStream.concat(DoubleStream.of(0.0, 1.0, 2.0),
                DoubleStream.of(3.0, 4.0, 5.0))
                .boxed()
                .collect(Collectors.toList());
        assertThat(doubleList).containsOnly(0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
    }

    @Test
    public void charsからのストリーム生成() {
        // chars
        String str = "abcde1234あいう";
        str.chars()
                .forEach(System.out::println);
        str.chars()
                .forEach(c -> System.out.println((char)c));

        int[] charArray = str.chars()
                .toArray();
        assertThat(charArray).containsOnly(97, 98, 99, 100, 101,
                49, 50, 51, 52,
                12354, 12356, 12358);
    }

    @Test
    public void codePointsからのストリーム生成() {
        // codePoints
        String emoji = "\uD83D\uDE04";
        emoji.codePoints()
                .forEach(System.out::println);
        emoji.codePoints()
                .mapToObj(Integer::toHexString)
                .forEach(System.out::print);

        int[] emojiInt = emoji.codePoints().toArray();
        assertThat(emojiInt).containsOnly(128516);
    }

    @Test
    public void Randomからのストリーム生成() {
        // ints
        Random intRandom = new Random(100);
        intRandom.ints(5, 1, 1000).forEach(System.out::println);

        List<Integer> list = intRandom.ints(5, 1, 1000)
                .boxed()
                .collect(Collectors.toList());
        assertThat(list).containsOnly(850, 399, 777, 503, 830);

        // longs
        Random longRandom = new Random(100);
        longRandom.longs(5, 1, 1000).forEach(System.out::println);

        List<Long> longList = longRandom.longs(5, 1, 1000)
                .boxed()
                .collect(Collectors.toList());
        assertThat(longList).containsOnly(36L, 55L, 415L, 942L, 722L);

        // doubles
        Random doubleRandom = new Random(100);
        doubleRandom.doubles(5, 1, 1000).forEach(System.out::println);

        List<Integer> doubleList = doubleRandom.doubles(5, 1, 1000)
                .boxed()
                .mapToInt(Double::intValue)
                .boxed()
                .collect(Collectors.toList());
        assertThat(doubleList).containsOnly(623, 237, 487, 680, 525);
    }

    @Test
    public void emptyによるストリーム生成() {
        Stream.empty().forEach(System.out::println);
        IntStream.empty().forEach(System.out::println);
        LongStream.empty().forEach(System.out::println);
        DoubleStream.empty().forEach(System.out::println);

        IntStream stream = IntStream.empty();
        List<Integer> list = stream.boxed().map(i -> i + 1).collect(Collectors.toList());
        assertThat(list).isEmpty();
    }

    @Test
    public void ファイル読み込みからのストリーム生成() throws IOException {
        // BufferReader
        try(BufferedReader reader = new BufferedReader(new FileReader("src/main/java/text/memo.txt"))) {
            Stream<String> stream = reader.lines();
            stream.forEach(System.out::println);
        } catch (IOException e) {
            throw e;
        }

        try(BufferedReader reader = new BufferedReader(new FileReader("src/main/java/text/memo.txt"))) {
            Stream<String> stream2 = reader.lines();
            List<String> list = stream2.collect(Collectors.toList());
            assertThat(list).containsOnly("aiueo", "かきくけこ");
        } catch (IOException e) {
            throw e;
        }

        // Files
        Path path = Paths.get("src/main/java/text/memo.txt");
        try(Stream<String> stream = Files.lines(path)) {
            stream.forEach(System.out::println);
        } catch (IOException e) {
            throw e;
        }

        try(Stream<String> stream = Files.lines(path)) {
            List<String> list = stream.collect(Collectors.toList());
            assertThat(list).containsOnly("aiueo", "かきくけこ");
        } catch (IOException e) {
            throw e;
        }
    }

    @Test
    public void ディレクトリ読み込みからのストリーム生成() {
        Path path = Paths.get("src/main/java/text");

        // find
        try {
            Files.find(path, 2, (p, attr) -> p.toString().endsWith("txt"))
                    .forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            List<String> list =
                    Files.find(path, 2, (p, attr) -> p.toString().endsWith("txt"))
                            .map(Path::toString)
                            .collect(Collectors.toList());
            assertThat(list).containsOnly("src\\main\\java\\text\\memo.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // list
        try {
            Files.list(path).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            List<String> list =
                    Files.list(path)
                            .map(Path::toString)
                            .collect(Collectors.toList());
            assertThat(list).containsOnly("src\\main\\java\\text\\memo.txt",
                    "src\\main\\java\\text\\access.log",
                    "src\\main\\java\\text\\csv");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // walk
        try {
            Files.walk(path).forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            List<String> list =
                    Files.walk(path)
                            .map(Path::toString)
                            .collect(Collectors.toList());
            assertThat(list).containsOnly("src\\main\\java\\text",
                    "src\\main\\java\\text\\memo.txt",
                    "src\\main\\java\\text\\access.log",
                    "src\\main\\java\\text\\csv",
                    "src\\main\\java\\text\\csv\\data.csv");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

ソースは一応あげときました。
github.com


終わり。