Java Lambda 表达式

函数式接口的概念

函数式接口本质上仍是一个 接口,但有一个严格约束:必须且只能有一个抽象方法(Abstract Method)

@FunctionalInterface
public interface MyFunction {
    void apply(); // 唯一的抽象方法
}

注:可以有多个默认方法(default)、静态方法(static)、可以重写 Object 的方法,但只能有一个抽象方法

注:@FunctionalInterface 注解不是必须的,但强烈建议加上,因为它提供了:

  • 编译期校验,防止误加多个抽象方法
  • 提升代码可读性,直接告诉别人,这是给 Lambda 用的函数式接口


函数式接口的写法

传统写法

// 定义接口和抽象方法
interface Strategy {
    int apply(int x);
}

// 实例化对象,并实现抽象方法
Strategy s = new Strategy() {
    @Override
    public int apply(int x) {
        return x * 2;
    }
};

Lambda 写法

// 创建一个 Strategy 接口的实现,并声明 x 为其中唯一的抽象方法的入参,
// x -> x * 2 是 对 apply(int x) 方法的实现,其中 x 是方法参数, x * 2 是方法体的返回值
Strategy s = x -> x * 2;

调用方式

int result = s.apply(10);


Lambda 其它写法

// 实现是多行逻辑时
Strategy s = x -> {
   int result = x * 2;
   result += 10;
   return result;
};

// 多个入参时
Strategy s = (a, b) -> {
  int sum = a + b;
  return sum * 2;
};

// 入参带类型时
Strategy s = (int x) -> {
    if (x < 0) {
        return 0;
    }
    int result = x * 2;
    return result;
};


实际应用场景

如下,开发者定义实现,框架负责执行:

.authorizeHttpRequests(auth -> {
    auth.requestMatchers("/admin/**").hasRole("ADMIN");
    auth.requestMatchers("/user/**").hasRole("USER");
    auth.anyRequest().authenticated();
});

函数式接口的意义于:你只负责提供“行为”实现,让调用方(框架 / API)掌控执行时机。也就是把“行为”抽象成参数,使调用方(框架/API)可以在合适的时机、以合适的方式去执行,从而实现解耦、组合与扩展。

函数式接口在早已存在,但由于语法成本高、使用不便,主要用于设计模式;但 Lambda 的出现简化了其语法、降低使用复杂度,使函数式编程成为了主流实践。




举报

© 著作权归作者所有


0