前言

Java8 的发布带来了诸多革命性的新特性,其中 Lambda 表达式是函数式编程思想在 Java 中的落地实现,极大简化了代码编写方式。本文将从 Lambda 表达式的基础语法、使用场景、省略规则等维度,全方位解析这一核心特性。

Java8 新特性如下:

  • Lambda 表达式

  • 函数式接口

  • Stream API

  • 新的日期时间 API

  • 接口默认方法 + 静态方法

  • Optional 类

  • 方法引用

一、Lambda 表达式初识

在传统面向对象编程中,我们常常需要通过匿名内部类实现接口,例如对数组进行排序:

java

import java.util.Arrays;
import java.util.Comparator;

public class Test1 {
    public static void main(String[] args) {
        Integer[] arr = {5,7,1,8,9,3};

        // 传统匿名内部类写法
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        
        // Lambda表达式简化写法
        Arrays.sort(arr,
           (Integer o1, Integer o2) -> {
                return o1 - o2;
            }
        );
        System.out.println(Arrays.toString(arr));
    }
}

从代码中可以明显看出,Lambda 表达式摆脱了面向对象语法的束缚,直接聚焦 “做什么” 而非 “谁去做”。

二、函数式编程思想

2.1 核心对比

  • 面向对象编程:先找对象,让对象完成具体操作,语法上必须遵循类、对象的约束。
  • 函数式编程:忽略复杂的面向对象语法,核心关注 “执行什么逻辑”,Lambda 表达式是函数式编程在 Java 中的核心体现。

三、Lambda 表达式核心语法

3.1 基础语法格式

() -> {
    // 方法体
}
  • ():对应接口抽象方法的形参列表
  • ->:Lambda 操作符,用于分隔参数和方法体
  • {}:对应接口抽象方法的方法体

3.2 使用场景

Lambda 表达式仅能简化函数式接口的匿名内部类写法

  • 函数式接口定义:有且仅有一个抽象方法的接口,可通过@FunctionalInterface注解标识(注解非必须,但推荐使用,编译器会校验接口是否符合函数式接口规范)。
错误示例(非函数式接口)

java

public class Test2 {
    public static void main(String[] args) {
        // 编译报错:Animal不是函数式接口
        testSay(() -> {
            System.out.println("旺旺旺......");
        });
    }

    public static void testSay(Animal animal){
        animal.say();
    }
}

@FunctionalInterface // 注解校验失败,因为存在两个抽象方法
abstract class Animal{
    public abstract void say();
    public abstract void eat();
}

四、Lambda 表达式省略规则

Lambda 表达式支持语法省略,核心口诀:左右遇一括号省,左侧推断类型省,能省则省

4.1 省略规则详情

  1. 参数类型可省略(编译器可通过上下文推断类型);
  2. 若仅有一个参数,参数类型省略的同时,()也可省略;
  3. 若方法体仅有一行代码,{}、分号、return需同时省略(三者缺一不可)。

简记口诀:
          左右遇一括号省
          左侧推断类型省
          能省则省略

4.2 完整示例对比

java

import java.util.Arrays;
import java.util.Comparator;

public class Test3 {
    public static void main(String[] args) {
        Integer[] arr = {5,7,1,8,9,3};

        // 1. 传统匿名内部类
        Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });

        // 2. Lambda完整格式
        Arrays.sort(arr, (Integer o1, Integer o2)->{
                return o1 - o2;
            }
        );

        // 3. Lambda省略格式(最终简化版)
        Arrays.sort(arr, (o1, o2) -> o1 - o2);

        System.out.println(Arrays.toString(arr));
    }
}

五、实战练习

练习 1:遍历集合(List/Set/Map)

java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class LambdaPractice1 {
    public static void main(String[] args) {
        // 遍历List
        List<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(1);
        list.add(3);
        list.add(9);
        list.add(2);
        list.forEach(num -> System.out.println(num));

        // 遍历Set
        Set<Integer> set = new HashSet<>();
        set.add(5);
        set.add(1);
        set.add(3);
        set.add(9);
        set.add(2);
        set.forEach(num -> System.out.println(num));

        // 遍历Map
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "tom");
        map.put(2, "jerry");
        map.put(3, "lucy");
        map.put(4, "make");
        map.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));
    }
}

练习 2:按字符串长度排序数组

java

import java.util.Arrays;

public class LambdaPractice2 {
    public static void main(String[] args) {
        String[] arr = {"a", "aaaa", "aa", "aaa"};
        
        // Lambda简化写法
        Arrays.sort(arr, (s1, s2) -> s1.length() - s2.length());
        
        System.out.println(Arrays.toString(arr)); // 输出:[a, aa, aaa, aaaa]
    }
}

总结

Lambda 表达式是 Java8 函数式编程的核心,其核心价值在于简化函数式接口的匿名内部类写法,让代码更简洁、聚焦业务逻辑。掌握其语法格式、使用场景(仅函数式接口)和省略规则,是灵活运用 Lambda 的关键。后续我们还会结合 Stream API 等特性,进一步讲解 Lambda 的实战场景。

更多推荐