1. ホーム
  2. java

[解決済み] ラムダ式はコードの行数を節約する以外に使い道があるのか?

2022-08-13 01:47:12

質問

ラムダ式はコードの行数を減らす以外に使い道があるのでしょうか?

ラムダが提供する特別な機能で、簡単には解決できなかった問題を解決したものはありますか?私が見た典型的な使い方は、これを書く代わりに

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());

どのように解決するのですか?

ラムダ式は、一般的にJavaで解決できる問題のセットを変更しませんが、私たちがもうアセンブリ言語でプログラミングしていないのと同じ理由で、特定の問題の解決を確実に容易にします。プログラマーの仕事から冗長なタスクを削除することで、生活が楽になり、そうでなければ手をつけなかったことを、(手動で) 作成しなければならないコードの量だけできるようになります。

しかし、ラムダ式は単にコード行数を節約するだけではありません。ラムダ式では 関数 を定義することができます。以前は回避策として匿名内部クラスを使用することができました。

最も重要なことは、ラムダ式は変換される関数インターフェースに対して独立して定義されるため、アクセスできる継承されたメンバはなく、さらに、関数インターフェースを実装する型のインスタンスにアクセスできないことです。ラムダ式内では thissuper は周囲の文脈と同じ意味を持つので、こちらも参照してください。 この答え . また、周囲のコンテキストのローカル変数の影になる新しいローカル変数を作成することはできません。関数を定義するという意図されたタスクのために、これは多くのエラー源を取り除きますが、それはまた、他の使用例については、たとえ関数インターフェイスを実装していても、ラムダ式に変換することができない匿名の内部クラスがあるかもしれないということを意味します。

さらに、コンストラクト new Type() { … } は新しい明確なインスタンスを生成することを保証しています (つまり new が常にそうであるように)。匿名内部クラスインスタンスは、常にその外部インスタンスへの参照を保持します。 static のコンテキストで作成された場合は、常に外部インスタンスへの参照を保持します。これに対して、ラムダ式では、外部インスタンスへの参照は this にアクセスした場合のみです。 this にアクセスした場合、あるいは非 static のメンバーで構成されます。そして、意図的に不特定多数のインスタンスを生成し、既存のインスタンスを再利用するかどうかを実装が実行時に決定できるようにします (参照 " ラムダ式は実行されるたびにヒープ上にオブジェクトを生成するのでしょうか? ").

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

意味と性能の両方に関する違いを考えると、ラムダ式はプログラマが将来的に特定の問題を解決する方法を変えるかもしれません。もちろん、新しい言語機能を利用した関数型プログラミングのアイデアを取り入れた新しいAPIも原因です。参照 Java 8のラムダ式とファーストクラスの値 .