Javaラムダ式の徹底解説!効果的な使い方と書き方について

目次
はじめに
本記事はIT会社勤務の100名程の研修生を見てきた元Java研修講師が、資格試験に出てきたり見かけることが多い「ラムダ式」について、特徴やなぜよく使われるのか解説していきます!!
ラムダ式
ラムダ式、資格試験にも出てきたり耳にすることが多いかもしれませんが、「なんか難しそう」「勉強してみたけど全然分からない」そう感じる人が多いと思います。自分もその1人でした。
ラムダ式が難しく感じる理由としては、「ラムダ式の単語の意味がわからない」「利点が分からない」「書き方が複雑」と自分が感じた理由はこの3つです。
if文などは、条件分岐で使う。と単語の意味で推測はできるが、ラムダ式と言われても聞き馴染みがないから難しく感じてしまいます。
if文は条件によって処理を分けたい。for文は特定の処理を繰り返し実行したい。など、使えば分かりやすい利点がありますが、ラムダ式は利点が分かりづらいです。
“`java
interface Greet {
void say();
}
public class Main {
public static void main(String[] args) {
// ラムダ式でGreetインターフェースを実装
Greet greet = () -> System.out.println(“こんにちは!”);
// 実行
greet.say();
}
}
“`
単純なラムダ式のコードですが、インターフェースを用意する必要があるのか。と思うことでしょう。しかし、通常だとGreetインターフェースを実装するクラスを作り、オーバーライドして表示処理を書き、Mainクラスでインスタンス生成をして呼び出す。のが一般的です。
ラムダ式を使えば、実装クラスを作らずにMainクラスで処理書いて呼び出せちゃいますよ。短くなるでしょ。そこに利点があります。と言われても、ピンとこないと思います。
ピンとこない理由は、上記のコードはとりあえずラムダ式を使いたいから書かれたコードで、ラムダ式の良さを活かしきれていないからです!ここからラムダ式の効果的な使い方を学んでいきます!
効果的なラムダ式
まずはラムダ式を使わないで書いたコードをお見せして、次にラムダ式を使って書いたコードをお見せします。見比べることで見えてくることもあると思います。
- ラムダ式を使わない場合
“`java
public class SortWithoutLambda {
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of(“banana”, “apple”, “kiwi”));
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.length() – b.length(); // 長さで比較
}
});
// [kiwi, apple, banana]
System.out.println(list);
}
}
“`
- ラムダ式を使う場合
“`java
public class SortWithLambda {
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of(“banana”, “apple”, “kiwi”));
Collections.sort(list, (a, b) -> a.length() – b.length());
// [kiwi, apple, banana]
System.out.println(list);
}
}
“`
まず、この2つのコードは用意された3つの英単語を文字数の昇順に並び替えるコードです。
見比べてみると、使わない場合では無名クラスを使ったりオーバーライドをしたり、本来行いたい「長さで比較」までの処理が5〜6行ほどあり深くて埋もれてしまいがちです。
それに比べてラムダ式を使用すると、長さの比較処理を書く1行だけで済むので可読性も高く、修正が必要な場合も修正箇所を見つけやすいです。記述内容自体は同じで、ラムダ式を使わないほうが構造をはっきりとさせて分かりやすくなっていますが、慣れてしまえばラムダ式を使ったほうが読みやすいと思います。
ラムダ式の書き方
ラムダ式の基本構文
基本的な書き方は、以下のようになります。
「(引数) -> { 処理内容 }」
この基本的な書き方から、数種類の書き方が存在しますのでそちらを説明していきます。
- 引数あり、処理1行⇨「()」省略OK(例外あり)
name -> System.out.println(“こんにちは、”+ name + “さん。”);
- 引数なし⇨「()」書く必要あり
() -> System.out.println(“こんにちは!”);
- 引数2つ⇨引数を「,」で区切る
(a, b) -> System.out.println(a + b);あああああああああああああああああ Windowsevofo
- 処理が複数行⇨「{}」と「return」が必要
(a, b) -> {
int result = a * b;
return result;
}
以上のように、ラムダ式で省略できたりできなかったりルールが複数あり難しく感じるかもしれませんが、なぜ省略されてるかを理解してしまえば難しさは無くなっていくと思います。
まとめ
一見難しく見えるラムダ式も、きちんと学習して覚えるところを覚えてしまえば、そこまで難しくないことに気づいてもらえたら幸いです。ラムダ式を使ってStream APIと組み合わせたりで、もっと効果的にラムダ式を使えたりするため、少しずつ学習を進めましょう!