旧サネの趣味と技術的勉強記録

趣味とかITとかプログラミングとかそんな感じのやつ

javaのラムダ式(1) 基本の形式

java8にてついにjavaにも表れたラムダ式
前々からjavaやっていて初めて見たときに、そのあまりにjava離れした見た目にぎょっとし、そしてそのまま見なかったことにした方も多いのでは。
というか自分がそうでした。

で、なんで2018年の今頃、ラムダ式について書き始めるのかってことなんですが、
まず自分がなんとなく使うようになってくると、
どうしても機械的に書くようになって結局これなんだったかいな? ってのをわかっている限り再確認したかったのが1つ。

そしてもう1つは、javaラムダ式ってまだ使ったことない方結構いると思うのです。
古のシステムの保守なんてやってるとjava1.5とか6とかで、
開発環境もわざわざ1.5で作ったりしていると。
しかし別の新しいシステムを作ることになり見てみると、最近のAPIなんかは1.8準拠でできてたりする。
当たり前のようにラムダ式の使用がデフォルトになっている。
とにかくサンプルコードをコピペしてなんとなく動くけど釈然としない。
でも見た目がキモチワルくて触りたくないからそのままそこの処理は封印する。
あるいはとにかくソースにラムダ式を入れないように、いつまで保守されるかわからない古のAPIを入れてよしとする……
というか自分がそうでした。

もちろんラムダ式に関してはすでにネット上に多くの情報があるのですが、
自分でも自分なりに何かしら書いておこうと思ったわけです。

というわけで、ラムダ式とはこんなやつです。
よく一緒にいるのを見る、stream、そしてforEachと一緒に。

final List<Integer> list = new ArrayList<Integer>();
for(int i = 0 ; i < 5 ; i++){
	list.add(i);
}

list.stream().forEach(i -> System.out.println(i));

正確に言うと、一番下のforEachメソッドの中身がラムダ式
いきなり->とか出てきてる上にこれまでのjavaの処理っぽくない。

というのもこれは結構ざっくり省略形にした見た目なのです。
ラムダ式というのは……
1.基本の形式は ( 引数 ) -> { 処理 } である
2.というか匿名クラスの変形だと思えばOK
と考えておけばいいと思います。

list.stream().forEach(i -> System.out.println(i));

は、動作結果としては

for(Integer i : list){
    System.out.println(i);
}

と同じです。
なんとなく、stream().forEach が名前の如く拡張for文の代わりをしているっぽいのは感じます。
そっち(stream、forEach)はまた別の話として改めて考えるとして。
それを踏まえて、省略されているところを付け加えたり形を変えたりしながら基本の形式に戻していきたいと思います。
まず、引数が1つの場合は、引数を囲む括弧が省略可能。
つまり省略しないで書くとこう。

list.stream().forEach((i) -> System.out.println(i));


次に、変数の型は暗黙的に推論されて省略されています。Integerのlistをループしてるわけですからね、Integerでしょうね。

list.stream().forEach((Integer i) -> System.out.println(i));


で、引数はこれでいいとして、処理の方は1行であれば{と}、そして文末セミコロンは省略できます。戻してみます。

list.stream().forEach((Integer i) -> {System.out.println(i);});


基本の形式、( 引数 ) -> { 処理 } に戻りました。
折角なので改行とか入れてみます。

list.stream().forEach((Integer i) -> 
    {
        System.out.println(i);
    }
);


こう見ると、このラムダ式って
「Integer型の引数i を持ち、その引数を標準出力に書き出す」メソッド
そっくりですね。
処理中にメソッドの定義を書く、これはまさしく匿名クラスなのでは?


続きは次の記事で。