文章目录
- Lambda 表达式:
- 基本语法:
- 例子:
- 匿名内部类:
- 语法:
- 例子:
- 对比:
- 相似之处:
- 区别:
- 示例比较:
Lambda 表达式:
Lambda 表达式是 Java 8 引入的一项功能,用于简化函数式接口的实现。Lambda 表达式提供了一种更为简洁和可读的方式来编写匿名函数,尤其是在函数式编程和处理集合时。
基本语法:
(parameters) -> expression
或者
(parameters) -> { statements; }
Lambda 表达式的主要特点包括:
- 参数列表(parameters): 与方法的参数列表相似,可以包含零个或多个参数。
- 箭头符号(->): 表示从参数到表达式或语句的映射。
- 表达式(expression)或语句块(statements): 表达式是单一的返回值,而语句块可以包含多个语句,并且有自己的作用域。
例子:
// Lambda 表达式实现 Runnable 接口
Runnable runnable = () -> System.out.println("Hello, Lambda!");// Lambda 表达式实现 Comparator 接口
Comparator<String> comparator = (s1, s2) -> Integer.compare(s1.length(), s2.length());
匿名内部类:
匿名内部类是在声明和创建对象的同时定义类的一种方式。通常用于创建只需使用一次的简单类或接口的实例。
语法:
new InterfaceName() {// 类的成员和方法
}
匿名内部类的主要特点包括:
- 没有类名: 匿名内部类没有显式的类名,类的定义和实例的创建合并在一起。
- 实现接口或继承类: 可以直接实现接口或继承抽象类,并在花括号中提供具体的实现。
例子:
// 匿名内部类实现 Runnable 接口
Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("Hello, Anonymous Inner Class!");}
};// 匿名内部类实现 Comparator 接口
Comparator<String> comparator = new Comparator<String>() {@Overridepublic int compare(String s1, String s2) {return Integer.compare(s1.length(), s2.length());}
};
对比:
- 语法: Lambda 表达式更为紧凑,语法更简洁。匿名内部类相对繁琐一些,需要使用关键字
new
和接口/类的名称。 - 作用域: Lambda 表达式和匿名内部类都可以访问外部变量,但有些细节上的差异,例如对于外部变量的访问是 final 还是 effectively final 等。
是的,匿名内部类和Lambda 表达式都是在 Java 中用于实现接口中的抽象方法的机制。虽然它们有一些相似之处,但也存在一些关键的区别。
相似之处:
-
实现接口的方式: 匿名内部类和Lambda 表达式都可以用于实现接口中的抽象方法。
-
单一抽象方法(SAM): 二者都通常用于实现只有一个抽象方法的接口,这样的接口被称为函数式接口。
区别:
-
语法:
- 匿名内部类: 使用关键字
new
创建一个没有明确类名的实例,并在花括号中提供实现。语法相对冗长。 - Lambda 表达式: 提供了更为紧凑的语法,不需要使用关键字
new
,而是使用箭头->
定义参数和实现。
- 匿名内部类: 使用关键字
-
作用域:
- 匿名内部类: 对于外部变量的访问,需要注意变量是 final 或 effectively final 的。变量在匿名内部类中具有封闭的作用域。
- Lambda 表达式: 具有对外部变量的捕获(capturing),但它们对外部变量的访问要求变量是 final 或 effectively final。Lambda 表达式对变量的引用是在运行时进行的。
-
关键字:
- 匿名内部类: 使用
new
关键字创建实例。 - Lambda 表达式: 更简洁,直接使用参数和箭头符号。
- 匿名内部类: 使用
示例比较:
匿名内部类实现 Runnable 接口:
Runnable runnable1 = new Runnable() {@Overridepublic void run() {System.out.println("Hello from Anonymous Inner Class!");}
};
Lambda 表达式实现 Runnable 接口:
Runnable runnable2 = () -> System.out.println("Hello from Lambda!");
在上述例子中,两者都实现了 Runnable 接口,分别使用匿名内部类和 Lambda 表达式。可以看到 Lambda 表达式更为紧凑,语法更为简洁。在实践中,Lambda 表达式通常用于实现简单的函数式接口,而匿名内部类则用于需要更复杂逻辑的场景。