Java 8で追加されたAPIの一つで、ラムダ式などの関数型プログラミングを記述できるようになる。
Streamはコレクションやリストなどを一か所に集めて、ごにょごにょ処理ができるようになる。その際に、中間処理や終端処理を終えると処理された結果を返すことで、 より自分が使いやすいデータとして扱えるようになる。
Streamの例
ElasticSearchのソースコードに
this.registry = new NamedXContentRegistry(
Stream.of(getDefaultNamedXContents().stream(), getProvidedNamedXContents().stream(), namedXContentEntries.stream())
.flatMap(Function.identity()).collect(toList()));
のコードを見てて、なんとなくこれは何かしらのリストのようなものを集めて最終的にリストで返しているんだなーってくらいに思って眺めてたけど、勉強のためにもう少し深く理解するために少し調べてみた。
stream()
List型などにあるメソッド。Stream型で使えるようにStream型を生成するメソッド。
Arrays.asList("one", "two", "three").stream();
Arrays.asList(new Moment(), new Moment(), new Moment(), new Moment()).stream();
Stream.of()
Stream型にしたリストなどを一気にまとめられるメソッド。
List<String> numbers = Arrays.asList("one", "two", "three");
Stream.of(numbers.stream(), numbers.stream(), numbers.stream());
flatMap()
まとめたリストを一個のリストにまとめるメソッド。このメソッドの中でforEachなどを使って処理を記述できる。
Stream.of(list1.stream(), list1.stream(), list1.stream())
.flatMap(t -> t).forEach(t -> System.out.println(t)); // "one", "two", "three", "one", "two", "three", "one", "two", "three"
Stream.of(list1.stream(), list1.stream(), list1.stream())
.forEach(t -> System.out.println(t)); // reference values
Function.identity()
値をそのまま返すメソッド。最初は何でこんなものがあるかと思ったけど、t -> t
のような書き方を メソッドやFunction::identity
みたいに記述できたほうが読みやすいっていう理由が多かった。
Stream.of(numbers.stream(), numbers.stream(), numbers.stream())
.flatMap(Funcion.indentity());
このstackoverflowがわかりやすかった。
collect()
ストリームの終端処理でCollectors型で返してくれるメソッド。そのメソッド内でさらに返す型(リストなど)を決められる。
Stream.of(numbers.stream(), numbers.stream(), numbers.stream())
.flatMap(Funcion.indentity())
.collect(~);
Collectors.toList()
Collectors型をList型で返すメソッド。これをcollectメソッド内で使うことができる。
Stream.of(numbers.stream(), numbers.stream(), numbers.stream())
.flatMap(Funcion.indentity())
.collect(toList());
最初のコードの説明
this.registry = new NamedXContentRegistry(
Stream.of(getDefaultNamedXContents().stream(), getProvidedNamedXContents().stream(), namedXContentEntries.stream())
.flatMap(Function.identity()).collect(toList()));
最初に戻って、上のコードが何をしているかというと、List型をStream型にしてからStream.of
でまとめて、flatMap
を使用することでListの中身を一つにし、そのあとにcollect
でCollectors型にして、その中でtoList
で最終的にList型にして返してることになる(長い)。
リストって表現じゃなくてコレクションのほうが良かったかもしんない。