Java8(一)--lambda表达式

一、背景:

JDK 8 是 Java 发展史上的里程碑版本,引入了许多革命性特性,极大提升了开发效率和代码可读性。

  1. Lambda 表达式
  2. 函数式接口(Functional Interface)
  3. Stream API
  4. 方法引用(Method References)
  5. 接口的默认方法与静态方法
  6. 新的日期时间 API(java.time)
  7. Optional 类
  8. 重复注解(Repeating Annotations)
  9. 类型注解(Type Annotations)
  10. 并行数组操作
  11. CompletableFuture
    ......

二、什么是lambda表达式:

Lambda 表达式是一种匿名函数(即没有名称的函数),广泛用于支持函数式编程范式的语言(如 Python、Java 8+、C#、JavaScript 等)。

它的核心目的是简化代码,尤其是在需要传递简单函数作为参数的场景中。

1、基础语法:

1. 标准形式
> 有一个参数,无返回值:(参数) -> { 方法体 } 或 参数 -> { 方法体 }

> 有多个参数,有返回值:(参数1, 参数2) -> { return 返回值; }

> 无参数,无返回值:() -> { 方法体 }

2、类型声明可选

Java 编译器可自动推断参数类型:

// 显式声明类型
(int x, int y) -> x + y

// 类型推断
(x, y) -> x * y

三、使用场景:

1、替代匿名内部类:

简化 Runnable、Comparator 等接口的实现:

// 传统匿名内部类
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Running");
    }
}).start();

// Lambda 简化
new Thread(() -> System.out.println("Running")).start();

2、集合操作:

结合 Stream API 处理数据:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());

3、函数式接口:

Lambda 需与函数式接口(仅含一个抽象方法的接口)配合使用:

// 自定义函数式接口
@FunctionalInterface
interface Calculator {
    int operate(int a, int b);
}

// 使用 Lambda
Calculator add = (a, b) -> a + b;
System.out.println(add.operate(5, 3)); // 输出 8

四、核心优势:

1、代码简洁性

减少模板代码(如匿名类的 new 和 @Override)。
示例:排序列表的代码对比:

// 传统方式
Collections.sort(list, new Comparator<Integer>() {
    @Override
    public int compare(Integer a, Integer b) {
        return b - a;
    }
});

// Lambda 方式
Collections.sort(list, (a, b) -> b - a);

2、函数式编程支持

支持高阶函数(如 map、filter、reduce)。
示例:链式处理集合:

list.stream()
    .filter(s -> s.startsWith("A"))
    .map(String::toUpperCase)
    .forEach(System.out::println);

3. 延迟执行(Lazy Evaluation)

结合 Stream 实现按需计算,优化性能:

Optional<Integer> first = numbers.stream()
                                 .filter(n -> n > 10)
                                 .findFirst();

五、局限性:

1.、仅限函数式接口

无法直接用于非函数式接口(如含多个抽象方法的接口)。

2.、变量捕获限制

Lambda 只能捕获 final 或 effectively final 的外部变量:

int offset = 10;
// 合法:offset 是 effectively final
Function<Integer, Integer> adder = x -> x + offset;
// 非法:修改 offset 后不再是 effectively final
offset = 20;

3、调试困难

匿名特性导致堆栈跟踪中无法显示 Lambda 名称。

六、最佳实践:

1、优先使用方法引用

进一步简化代码(尤其是调用现有方法时):

// Lambda 形式
list.forEach(s -> System.out.println(s));
// 方法引用形式
list.forEach(System.out::println);

2、避免复杂逻辑

若 Lambda 超过 3 行,改用普通方法或匿名内部类。

3、结合泛型增强复用性

定义通用函数式接口:

@FunctionalInterface
interface Transformer<T, R> {
    R transform(T input);
}

Transformer<String, Integer> toLength = s -> s.length();
posted @ 2019-06-09 16:03  Diamond-Shine  阅读(511)  评论(0)    收藏  举报