ラムダ式がよくわからない。
「Java8で導入された新しい文法。ローカルクラスと無名クラスを利用して記述する内容を省略して処理記述を簡潔にする。」ということだが、そもそも無名クラスもよくわからない(笑)。そんなものを使わなくてもなんとかなってきたからな。
無名クラス(匿名クラス / Anonymous Class)とは「名前を持たない使い捨てのクラスのことです。」と言われても、なんで無名クラスを使わないといけないのか、その状況がパッと頭に浮かばない。
多分、無名クラス(からさらに発展してラムダ式)を使った方がすっきりしたコードが書けるんだろうが、無名クラスでの処理が唯一の解ではないので、上に書いたように「別の書き方」で凌いできたのが俺である(笑)
ラムダ式はインターフェース(関数型インターフェース)を実装したオブジェクトを生成するもの。「ラムダ式を、関数型インターフェースの型として扱う」という言い方もあるようだが、「インタフェースの実装」の方が俺的にはしっくりくる。
インターフェースはわかる。標準インタフェースはよく使うし。
インタフェースとは「クラスが持つべき『メソッドの型(名前、引数、戻り値)』だけを定義した設計図のようなもの」である。
ラムダ式は「抽象メソッドが 1つだけ」のインタフェースの「その 1つだけの抽象メソッドを規定して」実装するものだ。
また新しい言葉が出てきたぞ。「抽象メソッド」とは「中身の無い名前だけのメソッド」だ。
例えば、以下のようなインタフェース。
interface Greeting {void sayHello();}
sayHello が「抽象メソッド」である。「引数の無い、戻り値もない sayHello という名前のメソッド」が存在しているだけのインタフェースが。
これを実装するラムダ式が、
Greeting greeting = () -> System.out.println("こんにちは!");
となる。
greeting というのが、このラムダ式の変数名である。
()というのは引数がないということ。Greeting インタフェースの sayHello メソッドには引数がないからな。
System.out.println("こんにちは!"); というのが、sayHello という「中身の無いメソッド」に与える「中身」である。sayHello メソッドは「こんにちは!」という文字列を標準出力に出力する処理であると規定している。
これでこのラムダ式の変数 greeting に、上記内容のメソッド sayHello が設定される。なのでこの変数.メソッドを
greeting.sayHello();
このように書いてやれば、標準出力(画面など)に「こんにちわ!」という文字列が表示される。
引数、戻り値がある例だと、
public interface BiFunction<T, U, R> {R apply(T t, U u);}
こういう「2つの引数(T型, U型)を受け取り、R型の結果を返す抽象メソッド apply」を実装するラムダ式は、例えば
BiFunction<String, Integer, Integer> stringAdder = (strNum, num) -> {return Integer.parseInt(strNum) + num;};
このようになる。引数として文字列と数値を渡して、引数の文字列を数値変換(Integer.parseInt(strNum))して引数の数値と足し、数値の戻り値を返すラムダ式だ。
これで、stringAdder という変数に実装した apply メソッドを
int sum = stringAdder.apply("100", 50);
このようにして呼べば、変数 sum には 150 がセットされる。
おお、なんかラムダ式わかってきたぞ。なるほど、なるほど。
無名クラスで書くと
BiFunction<String, Integer, Integer> stringAdder = new BiFunction<String, Integer, Integer>() {@Overridepublic Integer apply(String strNum, Integer num) {return Integer.parseInt(strNum) + num;}};
こうなるので、確かにラムダ式の方がすっきりはするな。
ちなみに <T> だ <R> という引数は、ジェネリクス(Generics / 型引数)というもの。俺は C#.NET の開発のときに初めて遭遇したが、ほんま最初は「何、これ?」だったな(笑)
引数や戻り値の型を指定しないインタフェースで使われる仮の名前だ。<T>じゃなく<X>とか<Z>って書いても良い。仮の名前だから。でも、まあ、<T>が一般的な引数の仮の名前、<R>は戻り値の仮の名前絵として使われることが多い。
BiFunction<T, U, R> というのは、引数<T><U>と戻り値<R>の型はなんでもいいので、呼ぶとき指定してねってことである。
ラムダ式の勉強をするだけで、色々な勉強ができるな(笑)

コメントする