Java8 Lambdas与匿名类
由于Java8最近发布,其全新的lambda表达式看起来非常酷,我想知道这是否意味着我们已经习惯的匿名类的消亡 我对此进行了一些研究,发现了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如集合的sort方法,该方法用于获取Comparator的匿名实例来执行排序:Java8 Lambdas与匿名类,java,lambda,java-8,anonymous-class,Java,Lambda,Java 8,Anonymous Class,由于Java8最近发布,其全新的lambda表达式看起来非常酷,我想知道这是否意味着我们已经习惯的匿名类的消亡 我对此进行了一些研究,发现了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如集合的sort方法,该方法用于获取Comparator的匿名实例来执行排序: Collections.sort(personList, new Comparator<Person>(){ public int compare(Person p1, Person p2){
Collections.sort(personList, new Comparator<Person>(){
public int compare(Person p1, Person p2){
return p1.firstName.compareTo(p2.firstName);
}
});
而且看起来非常简洁。所以我的问题是,有没有理由继续在Java8中使用这些类而不是Lambdas
编辑
同样的问题,但相反,使用Lambdas而不是匿名类有什么好处,因为Lambdas只能用于单个方法接口,这个新功能只是一个仅在少数情况下使用的快捷方式,还是真的有用?Lambdas虽然是一个很好的功能,但只适用于SAM类型。也就是说,只与一个抽象方法进行接口。只要接口包含多个抽象方法,它就会失败。这就是匿名类有用的地方 所以,不,我们不能忽略匿名类。仅供参考,您的
sort()
方法可以更加简化,方法是跳过p1
和p2
的类型声明:
Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));
您也可以在这里使用方法引用。您可以在Person
类中添加compareByFirstName()
方法,并使用:
Collections.sort(personList, Person::compareByFirstName);
或者,为firstName
添加一个getter,直接从方法中获取比较器
:
匿名内部类(AIC)可用于创建抽象类或具体类的子类。AIC还可以提供接口的具体实现,包括添加状态(字段)。AIC的实例可以在其方法体中使用this
来引用,因此可以对其调用其他方法,其状态可以随时间变化,等等。这些都不适用于lambda
我猜AIC的大多数用途是提供单个函数的无状态实现,因此可以用lambda表达式代替,但还有其他用途不能使用lambda。AIC在这里停留
更新
AICs和lambda表达式之间的另一个区别是,AICs引入了一个新的作用域。也就是说,名称是从AIC的超类和接口解析的,并且可以隐藏在词汇封闭环境中出现的名称。对于Lambda,所有名称都是按词汇进行解析的。Java8中的Lambda是为函数式编程引入的。您可以避免使用样板代码。我在lambda上看到了这篇有趣的文章
建议对简单逻辑使用lambda函数。如果使用Lambda实现复杂逻辑,则在出现问题时调试代码时会产生开销。匿名类的Lambda性能 启动应用程序时,必须加载并验证每个类文件 匿名类由编译器作为给定类或接口的新子类型进行处理,因此将为每个类或接口生成一个新的类文件 lambda在字节码生成方面不同,它们更高效,使用JDK7附带的invokedynamic指令 对于lambda,此指令用于将字节码中的lambda表达式延迟到运行时。(仅第一次调用指令) 结果,Lambda表达式将成为一个静态方法(在运行时创建)。
(stateles和statefull案例有一点不同,它们是通过生成的方法参数解决的)有以下区别: 1)语法 与匿名内部类(AIC)相比,Lambda表达式看起来整洁 2)范围 匿名内部类是一个类,这意味着它在内部类中定义了变量的作用域 然而,lambda表达式不是它自己的作用域,而是封闭作用域的一部分。 在使用匿名内部类和lambda表达式时,类似规则适用于super和此关键字。对于匿名内部类,该关键字表示本地范围,super关键字表示匿名类的超类。而对于lambda表达式,该关键字引用封闭类型的对象,super将引用封闭类的super类
//AIC
public static void main(String[] args) {
final int cnt = 0;
Runnable r = new Runnable() {
@Override
public void run() {
int cnt = 5;
System.out.println("in run" + cnt);
}
};
Thread t = new Thread(r);
t.start();
}
//Lambda
public static void main(String[] args) {
final int cnt = 0;
Runnable r = ()->{
int cnt = 5; //compilation error
System.out.println("in run"+cnt);};
Thread t = new Thread(r);
t.start();
}
3)性能
在运行时,匿名内部类需要类加载、内存分配、对象初始化和非静态方法调用,而lambda表达式是纯编译时活动,在运行时不会产生额外成本。所以和匿名内部类相比,lambda表达式的性能更好**
**我确实意识到这一点并不完全正确。详情请参阅以下问题 - lambda语法不需要编写java可以推断的明显代码
- 通过使用
,lambda在编译时不会转换回匿名类(Java不需要创建对象,只需要关心方法的签名,就可以绑定到方法而不创建对象)invoke dynamic
- lambda更强调我们想做什么,而不是我们必须做什么才能做到
comparator.comparating(Person::getFirstName)
,如果getFirstName()
是返回firstName+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| | Lambdas | Anonymous classes |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Definition | An anonymous method that can be created without belonging| An inner class without a name. |
| | to any class | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Scope of variables of main class | Available | Not available |
| (this and super keywords also) | | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Lines of codes | Reduced the lines of code. It’s a short form of | Have more lines of code compared to lambdas |
| | anonymous class. | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Criteria for creating | Needs to be Functional Interface, ie interface with | Can use interfaces(including Functional |
| | only one abstract method. Example : Runnable Interface | interfaces) and abstract classes to create. |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Example: | Runnable r = ()->{System.out.println("Hello World");}; | Runnable r = new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | System.out.println("Hello World"); |
| | | } |
| | | }; |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("in run");
}
};
Thread t = new Thread(r);
t.start();
}
//syntax of lambda expression
public static void main(String[] args) {
Runnable r = ()->{System.out.println("in run");};
Thread t = new Thread(r);
t.start();
}
//AIC
public static void main(String[] args) {
final int cnt = 0;
Runnable r = new Runnable() {
@Override
public void run() {
int cnt = 5;
System.out.println("in run" + cnt);
}
};
Thread t = new Thread(r);
t.start();
}
//Lambda
public static void main(String[] args) {
final int cnt = 0;
Runnable r = ()->{
int cnt = 5; //compilation error
System.out.println("in run"+cnt);};
Thread t = new Thread(r);
t.start();
}
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| | Lambdas | Anonymous classes |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Definition | An anonymous method that can be created without belonging| An inner class without a name. |
| | to any class | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Scope of variables of main class | Available | Not available |
| (this and super keywords also) | | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Lines of codes | Reduced the lines of code. It’s a short form of | Have more lines of code compared to lambdas |
| | anonymous class. | |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Criteria for creating | Needs to be Functional Interface, ie interface with | Can use interfaces(including Functional |
| | only one abstract method. Example : Runnable Interface | interfaces) and abstract classes to create. |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Example: | Runnable r = ()->{System.out.println("Hello World");}; | Runnable r = new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | System.out.println("Hello World"); |
| | | } |
| | | }; |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+