lamdba

1. 匿名函数-简化代码、聚焦核心逻辑-必须依赖函数式接口:

接口名抽象方法入参返回值用途
Runnable void run() 无参无返回的执行逻辑
Consumer<T> void accept(T t) T 类型 消费一个参数(仅处理,不返回)
Supplier<T> T get() T 类型 生产一个参数(无参有返回)
Function<T, R> R apply(T t) T 类型 R 类型 转换参数(入参出参不同)
Predicate<T> boolean test(T t) T 类型 boolean 判断条件(返回布尔值)
BiFunction<T,U,R> R apply(T t, U u) T+U 类型 R 类型 两个入参的转换逻辑
BinaryOperator<T> T apply(T t1, T t2) T+T 类型 T 类型 两个同类型入参,返回同类型结果

2. 要求:

  • 局部变量:必须是 final 或「事实上的 final」(即变量赋值后不再修改);
  • 成员变量 / 静态变量:无限制(可修改)。

原理:Lambda 捕获局部变量时,会复制变量的值(而非引用),因此要求变量不可变,避免多线程下的一致性问题;成员变量存储在堆中,Lambda 可通过 this 引用访问,因此无限制。

3. 高级:方法引用:

方法引用是 Lambda 的「语法糖」,当 Lambda 逻辑仅为调用一个已存在的方法时,可简化为方法引用,进一步提升可读性。

类型语法示例对应 Lambda
静态方法引用 类名::静态方法 Integer::parseInt str -> Integer.parseInt(str)
实例方法引用(特定对象) 对象::实例方法 System.out::println s -> System.out.println(s)
实例方法引用(任意对象) 类名::实例方法 String::toUpperCase str -> str.toUpperCase()
构造方法引用 类名::new ArrayList::new () -> new ArrayList<>()

4. 与 Optional 结合用于解决空指针的工具,结合 Lambda 可简化空值处理逻辑

// 传统空值判断
String str = "Java Lambda";
if (str != null) {
    System.out.println(str.length());
}

// Optional + Lambda
Optional<String> optional = Optional.ofNullable(str);
// 存在值时执行
optional.ifPresent(s -> System.out.println(s.length()));
// 存在值返回处理结果,否则返回默认值
int length = optional.map(String::length).orElse(0);
System.out.println(length); // 11

5. 与 CompletableFuture 结合(异步编程)

// 异步执行任务
CompletableFuture.supplyAsync(() -> {
    // 模拟耗时操作(如网络请求、数据库查询)
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "异步任务结果";
}).thenAccept(result -> {
    // 任务完成后处理结果(Lambda 作为回调)
    System.out.println("接收结果:" + result);
}).exceptionally(ex -> {
    // 异常处理
    System.out.println("异常:" + ex.getMessage());
    return "默认值";
});

6. lamdba实现原理

Lambda 表达式并非语法糖这么简单,其底层实现与匿名内部类完全不同:
  1. 编译阶段:Lambda 表达式不会生成单独的 .class 文件(匿名内部类会生成 外部类$1.class 等文件);
  2. 运行阶段:JVM 通过 invokedynamic 指令(动态调用)生成 Lambda 对应的方法(存储在外部类中),并通过「方法句柄」绑定到函数式接口;
  3. 性能:Lambda 比匿名内部类更高效 —— 避免了匿名内部类的类加载、实例化开销,且 invokedynamic 指令会缓存调用点,提升执行效率。

7. 注意点

Lambda 中的 this 指向外层类的实例(而非 Lambda 自身,因为 Lambda 不是类 / 对象),与匿名内部类相反。

避免将复杂逻辑写入 Lambda,单行逻辑最适合 Lambda,多行逻辑建议抽成方法。

8. 总结

  1. 核心本质:Lambda 是函数式接口抽象方法的匿名实现,依赖 @FunctionalInterface
  2. 语法简化:遵循「能省则省」原则(参数类型、括号、大括号、return 均可省);
  3. 核心场景:Stream 流处理、集合遍历、异步回调、自定义函数式接口;
  4. 高级用法:方法引用、变量捕获、Optional/CompletableFuture 结合;
  5. 避坑重点:this 指向、异常处理、可读性、多接口场景限制。

合理使用可大幅简化代码,过度使用(如嵌套复杂逻辑)反而会降低可读性。在 JDK 8+ 开发中,Lambda + Stream 是处理集合的标配,掌握其核心用法和原理,能显著提升开发效率。

 

posted @ 2025-12-14 10:02  永不熄灭的火  阅读(3)  评论(0)    收藏  举报