java 之匿名内部类 与 Lambda 表达式

Lambda 表达式:

Lambda 表达式是 Java 8 引入的一项功能,用于简化函数式接口的实现。Lambda 表达式提供了一种更为简洁和可读的方式来编写匿名函数,尤其是在函数式编程和处理集合时。

基本语法:
(parameters) -> expression

或者

(parameters) -> {
    
     statements; }

Lambda 表达式的主要特点包括:

  1. 参数列表(parameters): 与方法的参数列表相似,可以包含零个或多个参数。
  2. 箭头符号(->): 表示从参数到表达式或语句的映射。
  3. 表达式(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() {
    
    
    // 类的成员和方法
}

匿名内部类的主要特点包括:

  1. 没有类名: 匿名内部类没有显式的类名,类的定义和实例的创建合并在一起。
  2. 实现接口或继承类: 可以直接实现接口或继承抽象类,并在花括号中提供具体的实现。
例子:
// 匿名内部类实现 Runnable 接口
Runnable runnable = new Runnable() {
    
    
    @Override
    public void run() {
    
    
        System.out.println("Hello, Anonymous Inner Class!");
    }
};

// 匿名内部类实现 Comparator 接口
Comparator<String> comparator = new Comparator<String>() {
    
    
    @Override
    public int compare(String s1, String s2) {
    
    
        return Integer.compare(s1.length(), s2.length());
    }
};

对比:

  1. 语法: Lambda 表达式更为紧凑,语法更简洁。匿名内部类相对繁琐一些,需要使用关键字 new 和接口/类的名称。
  2. 作用域: Lambda 表达式和匿名内部类都可以访问外部变量,但有些细节上的差异,例如对于外部变量的访问是 final 还是 effectively final 等。

是的,匿名内部类和Lambda 表达式都是在 Java 中用于实现接口中的抽象方法的机制。虽然它们有一些相似之处,但也存在一些关键的区别。

相似之处:

  1. 实现接口的方式: 匿名内部类和Lambda 表达式都可以用于实现接口中的抽象方法。

  2. 单一抽象方法(SAM): 二者都通常用于实现只有一个抽象方法的接口,这样的接口被称为函数式接口。

区别:

  1. 语法:

    • 匿名内部类: 使用关键字 new 创建一个没有明确类名的实例,并在花括号中提供实现。语法相对冗长。
    • Lambda 表达式: 提供了更为紧凑的语法,不需要使用关键字 new,而是使用箭头 -> 定义参数和实现。
  2. 作用域:

    • 匿名内部类: 对于外部变量的访问,需要注意变量是 final 或 effectively final 的。变量在匿名内部类中具有封闭的作用域。
    • Lambda 表达式: 具有对外部变量的捕获(capturing),但它们对外部变量的访问要求变量是 final 或 effectively final。Lambda 表达式对变量的引用是在运行时进行的。
  3. 关键字:

    • 匿名内部类: 使用 new 关键字创建实例。
    • Lambda 表达式: 更简洁,直接使用参数和箭头符号。

示例比较:

匿名内部类实现 Runnable 接口:

Runnable runnable1 = new Runnable() {
    
    
    @Override
    public void run() {
    
    
        System.out.println("Hello from Anonymous Inner Class!");
    }
};

Lambda 表达式实现 Runnable 接口:

Runnable runnable2 = () -> System.out.println("Hello from Lambda!");

在上述例子中,两者都实现了 Runnable 接口,分别使用匿名内部类和 Lambda 表达式。可以看到 Lambda 表达式更为紧凑,语法更为简洁。在实践中,Lambda 表达式通常用于实现简单的函数式接口,而匿名内部类则用于需要更复杂逻辑的场景。

猜你喜欢

转载自blog.csdn.net/weixin_74850661/article/details/135033019