26
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラムダ式に戸惑った時の備忘録

26
Posted at

はじめに

これまでの案件で、比較的古いバージョンのJavaに触れることが多く、
ラムダ式に馴染みがありませんでした。
しかし、とある案件で実装中にラムダ式を使う場面があり、最初は->など馴染みのない記号があり、苦手意識がありました。そこで、今回はラムダ式の基礎的な部分について、初見で引っかかった点や、調べながら実装した経験を備忘録として整理してみます。

ラムダ式とは

ラムダ式とは、簡単にいうと「抽象メソッドが1つだけのインターフェース(関数型インターフェース)」に対して、処理を簡潔に記述するための書き方です。
従来の書き方と比較すると、以下のように記述を省略できます。

※インターフェースクラスは以下を準備します。

public interface MessageOutput {
    void print(String message);
}

⚪︎従来の書き方

public class LambdaTest {

    public static void main(String[] args) {

        MessageOutput output = new MessageOutput() {
            @Override
            public void print(String message) {
                System.out.println("メッセージ: " + message);
            }
        };

        output.print("ラムダTEST");
    }
}

⚪︎ラムダ式(省略した記法)

無名クラスで実装していた処理のうち、「メソッド定義部分」が省略され、
処理内容だけを簡潔に書けるようになっています。
 ※無名クラスとは、クラス名を定義せずにその場でクラスを実装する書き方です。
 一度しか使わない処理などで、別途クラスを作成する手間を省くために使用されます。

public class LambdaTest {

    public static void main(String[] args) {
        MessageOutput output = message -> System.out.println("メッセージ: " + message);
        output.print("ラムダTEST");
    }
}

引っかかった点と分かった点

初めてラムダ式を見た時、以下の点に引っかかりました。

1.引数の書き方
2.-> の意味
3.なぜこの記法だけで動くのか。

特に2.の -> は「左側が引数、右側が処理」という意味になっているものが、
最初はただの記号として見えてしまい、どのように読み取ればよいのか分かりませんでした。

そこで実際のコードを分解して考えてみました。

message -> System.out.println(message);

① message(引数)
② ->(引数と処理をつなぐ記号)
③ System.out.println(message)(実行される処理)

このように、「messageを受け取って、その内容を出力する処理」と読むことで、
少しずつ理解しやすくなりました。
また、従来の無名クラスはメソッド名や型を含めて記述していましたが、
ラムダ式では実装するメソッドが1つに決まっているため、
それらを省略して処理内容だけを書くことができます。どのメソッドを実装するかが明確なため、「どの処理か」を書く必要がなく、「何をするか」だけに集中して記述できる点が便利な点です。
この、「前提があるから省略できる」という点が、最初は少し分かりづらかったです。

※なお、ラムダ式では、引数の数によって以下の通り、書き方が少し変わります。

▫️引数なし

引数がない場合は () のみで記述します。

() -> System.out.println("ラムダTEST") 

▫️引数1つ

引数が1つの場合は () を省略することができます。

message -> System.out.println(message)

▫️引数2つ

引数が2つ以上の場合は () が必須となります。

(a, b) -> a.compareTo(b)

実際に試したこと

実際の現場の中で、一覧データの処理を行う際に、ラムダ式を使用する場面がありました。
例えば、工事機器名のリストに対して、「機器名を名前順に1件ずつ出力する」といった処理です。
従来の書き方では、以下のように、for文で書くことが多かったです。

⚪︎従来の書き方

List<String> equipmentNames = Arrays.asList("変圧器", "遮断器", "ケーブル");

// ソート処理
equipmentNames.sort(new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

// 出力
for (String equipmentName : equipmentNames) {
    System.out.println(equipmentName);
}

⚪︎ラムダ式

コード量が減り、意図が分かりやすくなったと思います。

List<String> equipmentNames = Arrays.asList("変圧器", "遮断器", "ケーブル");

// ソート処理
equipmentNames.sort((a, b) -> a.compareTo(b));

// 出力
equipmentNames.forEach(equipmentName -> System.out.println(equipmentName));

まとめ

 初めて見た時は->などがただの記号に見えて抵抗がありました。しかし実際に調べて分解してみてみると「記述が簡潔になることもある」ということに気づきました。ただ、「短く書けること」と「読みやすいこと」は必ずしも同じではないと思いました。慣れていない段階では、逆に処理の意図が追いづらく感じることもありましたので、使い所を意識する事が大事であると感じました。また、これまで触れたことがないこともあり、多少学習コストがかかるとも感じました。
 今回は基本的な部分しか触れていませんでしたが、ラムダ式と組み合わせて利用できるAPIが数多く備わっているため、今後はそれらも含め、理解を深めていけたらと思います。

26
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?