Java8から新たにラムダ式が導入された。 ラムダ式とは簡単に言うと匿名クラスを簡潔に記述できる文法である。
前記事「Comparatorを使ってListをソートする」で作成したComparatorのサンプルをラムダ式に書き換えてみる。 まずはComparatorを使った前回のサンプル。
import java.util.*;
public class Test{
public static void main(String[] args){
// ソートするList
List<String> list = new ArrayList<String>();
list.add("03");
list.add("1");
list.add("002");
// Comparatorを実装した匿名クラス
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
}
};
// ソート実行
Collections.sort(list, comparator);
// Listの中身を出力
System.out.println(list);
}
}
これをラムダ式に書き換えると以下のようになる。
import java.util.*;
public class Test{
public static void main(String[] args){
// ソートするList
List<String> list = new ArrayList<String>();
list.add("03");
list.add("1");
list.add("002");
// ソート実行
Collections.sort(list, (o1, o2) -> {return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));});
// Listの中身を出力
System.out.println(list);
}
}
下記がラムダ式を用いているところである。ロジックを引数に渡しているように見えるため関数型インタフェースとも呼ばれる。
(o1, o2) -> {return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));}
匿名クラスの記述を大幅に省略しているのがわかるだろう。左の()の中が引数、右の{}の中がロジックである。
匿名クラスの以下青太字の部分を抜き出したと思えばよい。
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
}
};
ラムダ式
(o1, o2) -> {return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));}
なお匿名クラスをラムダ式にする場合、インタフェースは抽象メソッドを1つだけしか持ってはならない。2つ以上持っていると、どのメソッドをラムダ式で記述しているか判別できないためである。 また引数が1つしかない場合は、丸括弧を省略して、もっと簡潔に記載が可能。
arg1 -> {System.out.println(arg1);}
簡単にラムダ式の説明をしたが、果たしてラムダ式の利用価値はどれくらいなのか? 前述のとおりラムダ式は匿名クラスを簡潔に記載する記述方式である。 しかし、コードを書いてて匿名クラスを使う頻度はどれくらいなのだろう? 頻繁に使うわけでもない匿名クラスを簡潔に書けたとして、そんなの嬉しいのだろうか? なぜこんなに話題になっているのだろうか?
確かに匿名クラスを簡潔に書くだけなら、飛び上がって喜ぶほどではないかもしれない。 ただ今後ラムダ式を利用したAPIが増える可能性がある。Java8でも、既にListの繰り返し処理を簡潔に記載できるようになったり(Iterable#forEach)、Stream APIでラムダ式が利用できるようになっている。 今後、利用頻度があがりそうである。
また簡潔に書くことによって、インタフェースが何なのかわかりづらくなったり、比較的処理が複雑なロジックをラムダ式に書くとかえって見づらいなどのデメリットもあるであろう。 メリット・デメリットについては未知の部分もあるため、実際に使っていく上で理解していけばよいかと思う。
ラムダ式やJava8で新たに導入された機能については、参考書を1冊持っておくとよいかもしれない。