今日のjavaおっかけ(20150508):Stream API 2

そして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))

これの型は結局なにになってるのかを調べていくか.