そしてstream API に戻る…!
目次とぶっつぶつテーマ
http://snoopopo.hatenablog.com/entry/2015/04/14/102732
今日のテーマ:Stream API 2
前回でデフォルトメソッドをやったので、stream API に戻る.
今回の趣旨は、以下の strem API たるものを使った例で、疑問に思った
List<String> names = Arrays.asList("hoge hoge", "poyo poyo", "popopopopo."); names.forEach(name -> System.out.println(name));
java.lang.Iterable クラスの default void forEach(Consumer<? super T> action) メソッドの中身を見ていく.
デフォルトメソッドなので、処理の実装が Iterable インタフェースに書かれているはずだ。
java.lang.Iterable インタフェースの forEach メソッド
というわけで中身を見ていく.
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
この中の
Objects.requireNonNull(action);
の部分は、java7で追加されたものだ.
これは既に id:nowokay さんが1ヶ月ほど前に記事にしてた*1のを見てなんとなく知ってるので、後回し.
気になるのは、引数の型 Consumer の部分だ.ラムダ周りのことで最近ちょくちょく見る型なので、これを見ていく.
default void forEach(Consumer<? super T> action) {
java.util.function.Consumer
中を見てみるとクラスでなく、インタフェースでした. しかも、@FunctionalInterface がついているので、関数型インタフェース.ここ*2でやった.
acceptという唯一のメソッドをもってる.andThen っていうメソッドもあるけど、デフォルトメソッドは数に入らないみたいだな.
List<String> names = Arrays.asList("hoge hoge", "poyo poyo", "popopopopo."); names.forEach(name -> System.out.println(name));
もとのこの例でいうと、forEachに渡している name -> System.out.println(name) がこのConsumerの実装なわけなので、
Consumer consumer = nameConsumer -> System.out.println(nameConsumer);
これ↑はコンパイル通る.
これを見ると、 -> というラムダの構文は関数型インタフェースを使っているので、 どんな関数型インタフェースにも代入できるということ?なのかと思ったが…
//これはいく Consumer consumer = nameConsumer -> System.out.println(nameConsumer); //これはコンパイルエラー Runnable runnable = nameRunnable -> System.out.println(nameRunnable); //これはいく…?? どこかのサンプルコードから抜粋させてもらったコード. Runnable object = () -> System.out.println("abc");
というよくわからない結果なので、
次回は、↑の2行目と3行目の違いを見ながら、
name -> System.out.println(name))
これの型は結局なにになってるのかを調べていくか.