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
終わり。