NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

駆け出しエンジニアの成長日記 ~ラムダ式編~

皆さんはじめまして、友野です。
初のブログ執筆ということで、緊張しています。友野です。

筆者は2023年で社会人2年目となります。生粋の文系育ちでプログラミング未経験だったこともあり、”コードを読めるが書けない”という現状の打破に向けて日々学習しています。
現在、社内で実施中のJava研修を受講しており、研修で学んだ内容をアウトプットする場としてブログを執筆していこうと思います。
本記事は、そんな駆け出しエンジニアの技術小出しブログとしてお立ち寄りいただけますと幸いです。。!

ラムダ式について知る

ラムダ式とは

関数型インタフェースのメソッドを使用し、メソッドの処理を短く記述できる構文です。
for文を使用して書くような繰り返しの処理に対し、冗長な部分を省略して記述できるというメリットがあります。
後述していますが、特にStream APIで要素の集合に一括処理を行う場合にメリットを発揮します。

ラムダ式の使い方

ラムダ式の記述形式は主に4パターン。

  1. 引数無し、戻り値なし
    () -> {処理}
  2. 引数無し、戻り値あり
    () -> {処理... return 値}
  3. 引数あり、戻り値なし
    変数 -> {処理}
  4. 引数あり、戻り値あり
    変数 -> {処理... return 値}

これらの形式に沿って記述します。
では、実際にコードを書く際はどのパターンを採用すべきなのでしょうか。順番に追っていきます。
まず、採用パターンを判断する条件として、関数型インターフェースが返す引数・戻り値の有無を当てはめます。
関数型インターフェースには@FunctionalInterfaceアノテーションが付与されています。

Consumerインターフェースを例にとって確認してみましょう。

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

Consumerインターフェースに定義されているacceptメソッドは、引数あり・戻り値なしであることが分かります。よって、記述形式は 3. のパターンとなります。

ここで、Consumerインターフェースを引数にとるOptional.ifPresent()メソッドを書いてみます。
Optional.ifPresent()とは、保持する値がnullでない場合のみ引数のConsumerインターフェースを実行するメソッドです。

Optional<String> hoge = Optional.ofNullable("hogehoge");

hoge.ifPresent(p -> System.out.println(p));

変数 -> {処理} の形式に当てはめるだけで簡単にラムダ式を書くことができました。
処理がワンステップで完了する場合は、{ }が省略可能です。

Stream APIの引数にラムダ式を使う方法

Stream APIとは、Listや配列など要素がまとまったものに対して処理を行うものです。
要素に対する複数の操作によって構成されます。

  • 要素をストリーム化(Listや配列などの要素からストリームを作成)
  • 中間処理(各要素に対する処理 例:Filter, map)
  • 終端処理(中間処理を終えた後のお片付け処理 例:Collect, Count, Findfirst)

中間処理で用意するメソッドの引数にラムダ式を使用する場合は、以下のようになります。

List<String> list = new ArrayList<>();
list.add("Bob1");
list.add("Bob2");
list.add("Bob3");
Optional<String> sample = list.stream().filter(fuga -> fuga.equals("Bob2")).findFirst();
sample.ifPresent(p -> System.out.println(p));

また、中間処理には複数のメソッドを入れ込むことが可能です。
Stream APIにラムダ式を組み合わせることで、複数の処理をまとめて記述することが出来ました。

おわりに

コードを追う際はさらっと読めるような箇所でも、いざ書くとなると手が止まってしまうものです。
ラムダ式は、変数のスコープを意識しなければ呼び出すタイミングによって処理結果内容が変わってしまうなど、かえって可読性を損ねる可能性もあります。
このように、基本構文を習得するだけでは仲良くなれそうにない奥の深い相手ですが、引き続き基礎固めに励みます。
最後までお読みいただき、ありがとうございました!
友野でした。