ラムダ式はコード行数を節約する以外に何か役に立つのでしょうか? 質問する

ラムダ式はコード行数を節約する以外に何か役に立つのでしょうか? 質問する

ラムダ式には、コード行を節約する以外に何か用途がありますか?

ラムダによって、簡単には解決できない問題を解決する特別な機能はありますか? 私が見た典型的な使用法は、次のように書く代わりに:

Comparator<Developer> byName = new Comparator<Developer>() {
  @Override
  public int compare(Developer o1, Developer o2) {
    return o1.getName().compareTo(o2.getName());
  }
};

ラムダ式を使用してコードを短縮することができます。

Comparator<Developer> byName =
(Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName());

ベストアンサー1

ラムダ式は、Java で解決できる問題全般を変えるものではありませんが、アセンブリ言語でプログラミングしなくなったのと同じ理由で、特定の問題の解決を確実に容易にします。プログラマーの作業から冗長なタスクを削除すると、作業が楽になり、(手動で) 作成しなければならないコードの量だけで、他の方法では手を付けなかったであろう作業も実行できるようになります。

しかし、ラムダ式は単にコード行数を節約するだけではありません。ラムダ式では、機能以前は回避策として匿名内部クラスを使用できたため、このような場合には匿名内部クラスを置き換えることができますが、一般的にはそうではありません。

最も注目すべきは、ラムダ式は変換先の関数インターフェースとは独立して定義されるため、継承されたメンバーにアクセスできず、さらに関数インターフェースを実装する型のインスタンスにアクセスできないことです。ラムダ式内では、this周囲superのコンテキストと同じ意味を持ちます。この答えまた、周囲のコンテキストのローカル変数をシャドウする新しいローカル変数を作成することもできません。関数を定義するという目的のタスクでは、これにより多くのエラー ソースが除去されますが、他のユース ケースでは、関数型インターフェイスを実装している場合でも、ラムダ式に変換できない匿名の内部クラスが存在する可能性があることも意味します。

さらに、この構造はnew Type() { … }新しい個別のインスタンスを生成することを保証します(newいつもそうします)。匿名の内部クラスインスタンスは、非コンテキスト¹で作成された場合、常に外部インスタンスへの参照を保持します。対照的に、ラムダ式は、必要なとき、つまり非メンバーにアクセスするときのみ、static参照を取得します。また、意図的に未指定のアイデンティティのインスタンスを生成するため、実装は実行時に既存のインスタンスを再利用するかどうかを決定できます(「thisthisstaticラムダ式は実行されるたびにヒープ上にオブジェクトを作成しますか?()。

これらの違いは、あなたの例にも当てはまります。匿名の内部クラス構造は常に新しいインスタンスを生成し、外部インスタンスへの参照をキャプチャする可能性もありますが、あなたのは、(Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())通常の実装ではシングルトンに評価される非キャプチャ ラムダ式です。さらに、.classハード ドライブにファイルは生成されません。

意味とパフォーマンスの両方の違いを考慮すると、ラムダ式は将来プログラマーが特定の問題を解決する方法を変える可能性があります。もちろん、新しい言語機能を利用した関数型プログラミングの考え方を取り入れた新しいAPIもその一因です。Java 8 ラムダ式とファーストクラスの値


¹ JDK 1.1 から JDK 17 まで。JDK 18 以降では、使用されていない場合、内部クラスは外部インスタンスへの参照を保持しない場合があります。互換性の理由から、内部クラスはシリアル化できない必要があります。これは、JDK 18 以降で内部クラスを (再) コンパイルし、ターゲットを JDK 18 以降にする場合にのみ適用されます。JDK-8271717

おすすめ記事