编程有一条原则如下:
避免创建不必要的对象:最好能重用对象,而不要在每次需要的时候就创建一个相同功能的新对象。
请看如下代码:
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
// 1、匿名内部类
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
//2、lambda表达式
Collections.sort(names, (a, b) -> b.compareTo(a));
是不是每次排序都创建了一个新的Comparator对象,导致性能降低?那么还主张使用Lambda表达式吗?
最初に質問に答えてください:
ソートのたびに新しい Comparator オブジェクトが作成され、パフォーマンスが低下しますか?では、ラムダ式の使用を今でも推奨していますか?
いいえ、主張します
根本的な理由
Lambda 式は匿名内部クラスの糖衣構文ではありません。つまり、Lambda 式の基礎となる実装は匿名内部クラスの実装ではありません。これらは実際には 2 つのものです
どうやって証明するの?
匿名内部クラスは、実際にはコンパイル中に ClassName$ 番号で名前が付けられたクラス ファイルを生成します。そのため、Lamdba 式の最下層も匿名内部クラスによって実装されている場合、同様に類似した内部ファイルが確実に生成されます。別のパッケージのクラスに例を記述し、コンパイルされた効果を確認します
匿名の内部クラスは InnerTest を実装します
これはクラス ファイルです。2 つあることがわかります
したがって、真実は 1 つだけです、笑、明らかに、これはまったく同じものではありません
根本的な違いを完全に示すために、それらのバイトコードを見てみましょう
InnerTest
LamdbaTest
しかし、このコマンドの名前から直接理解することができます:
と呼ばれます。動的呼び出し したがって、クラス ファイルにコンパイルされる匿名内部クラスとは異なり、Lamdba 式は次のようになります。静的メソッドにコンパイルされると、 -p を見ることで再度確認できます。生成されたメソッドは
lambda$main
もう 1 つ
実際、パフォーマンス、可読性、または一般的な傾向のいずれにおいても、lamdba 式はある意味で匿名の内部クラスよりもはるかに優れていることがわかります。とにかく、Java での使用に慣れており、とても気に入っています
各並べ替えでは新しい
Comparator
オブジェクトは作成されません。通常、Lambda 式に対応するインスタンスがメモリ内に生成されると、JVM はこのインスタンスを現在の環境で再利用します。具体的な手順については、次のリンクを参照してください: ラムダ式の実行時評価プログラムの可読性や開発効率の向上を前提として、Lambda式
Lambda 式内で匿名クラス オブジェクトを静的に宣言できます。
小さなオブジェクトの行き来は JVM にとって大きな問題ではありません;