编程有一条原则如下:
避免创建不必要的对象:最好能重用对象,而不要在每次需要的时候就创建一个相同功能的新对象。
请看如下代码:
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表达式吗?
First answer your question:
Is a new Comparator object created every time sorting, resulting in reduced performance? So do you still advocate using Lambda expressions?
No, claim
The fundamental reason
Lamdba expression is not syntactic sugar for anonymous inner classes at all. That is to say, the underlying implementation of Lambda expression is not the implementation of anonymous inner classes. They are actually two things
How to prove it?
Anonymous inner classes will actually generate a class file during compilation, named with ClassName$ numbers, so if the bottom layer of the Lamdba expression is also implemented by anonymous inner classes, a similarly similar inner file will definitely be generated.
So we simply write your example in classes under different packages, and then check the compiled effect
Anonymous inner class implements InnerTest
This is a class file, you can see there are two
lambda expression LamdbaTest
However, there is only one class file
So there is only one truth, haha, obviously, this is not the same thing at all
How is Lamdba expression implemented?
![](http://img.php.cn/upload/image/000/000/000/aa8d641701816079ad60c203b68cb8f5-4.png)
We can take a look at their bytecode, so that the underlying differences will be fully demonstrated
InnerTest
LamdbaTest
You can see that the instructions used by the two are different. When parsing the Lamdba expression, it uses the new invokedynamic instruction in Java 7. If you are familiar with this instruction, you may understand it instantly. If you are not familiar with it, you may understand it instantly. , you can ask Du Niang
But you can understand it directly from the name of this command: Dynamic call
Therefore, unlike anonymous inner classes that are compiled into a class file, Lamdba expressions are compiled into a static method , we can see it again by looking at -p. The generated method is called
lambda$main
One more thing
In fact, you can see that lamdba expressions are indeed much better than anonymous inner classes in a sense, whether it is performance, readability or general trend~ Haha, I want to say general trend because lamdba expressions can be used later There is wider room for optimization. Anyway, I am used to using it in java and I like it very much
Each sorting does not create a new
Comparator
object. Generally, once the instance corresponding to the Lambda expression is generated in memory, the JVM will reuse this instance in the current environment. For specific instructions, you can refer to this link: Run-Time Evaluation of Lambda ExpressionsOn the premise that it can improve program readability and development efficiency, it is recommended to use Lambda expression
You can statically declare an anonymous class object inside a Lambda expression;
Small objects that come and go are not a big problem for the JVM;