在 Java 中,Lambda 表达式(Java 8+)极大简化了集合操作、函数式编程和并发代码。以下是 开发中最常用、最实用的 Lambda 使用场景与方法,附带完整示例。


✅ 一、集合操作(Stream API)

1. 过滤(filter)

List<String> names = Arrays.asList("张三", "李四", "王五", "赵六");
List<String> longNames = names.stream()
    .filter(name -> name.length() > 2)
    .collect(Collectors.toList());
// 结果: ["张三", "李四", "王五", "赵六"](中文字符长度为1,此处仅为示例)

2. 映射(map)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> squares = numbers.stream()
    .map(n -> n * n)
    .collect(Collectors.toList());
// 结果: [1, 4, 9, 16]

3. 扁平化(flatMap)

List<List<String>> list = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
List<String> flat = list.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList());
// 结果: ["a", "b", "c", "d"]

4. 查找(findAny / findFirst)

Optional<String> result = names.stream()
    .filter(name -> name.startsWith("张"))
    .findAny(); // 或 findFirst()
if (result.isPresent()) {
    System.out.println(result.get());
}

5. 排序(sorted)

List<Person> sorted = personList.stream()
    .sorted(Comparator.comparing(Person::getAge))
    .collect(Collectors.toList());

// 降序
.sorted(Comparator.comparing(Person::getAge).reversed())

6. 分组(groupingBy)

java编辑

Map<String, List<Person>> byGender = personList.stream()
    .collect(Collectors.groupingBy(Person::getGender));
// {男=[张三, 李四], 女=[花木兰]}

7. 转 Map(toMap)

Map<String, Integer> nameAgeMap = personList.stream()
    .collect(Collectors.toMap(Person::getName, Person::getAge));
// {"张三"=23, "李四"=26, "花木兰"=25}

8. 统计(count / sum / max / min)

long count = personList.stream().count();

int totalAge = personList.stream()
    .mapToInt(Person::getAge)
    .sum();

OptionalInt maxAge = personList.stream()
    .mapToInt(Person::getAge)
    .max();

9.判断(anyMatch)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        boolean b = numbers.stream().anyMatch(num -> num % 2 == 0);
// true

10.查看(peek)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> squares = numbers.stream().peek(System.out::println).collect(Collectors.toList());
//[1,2,3,4]

✅ 二、函数式接口(常用内置)

接口 抽象方法 用途 示例
Function<T, R> R apply(T t) 转换类型 s -> s.length()
Predicate<T> boolean test(T t) 条件判断 n -> n > 0
Consumer<T> void accept(T t) 消费数据 System.out::println
Supplier<T> T get() 提供数据 () -> new Date()
Runnable void run() 无参无返回 () -> System.out.println("Hello")

示例:

// Predicate:过滤
Predicate<String> isEmpty = s -> s == null || s.isEmpty();

// Consumer:遍历处理
personList.forEach(p -> System.out.println(p.getName()));

// Supplier:延迟初始化
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> list = listSupplier.get();

✅ 三、方法引用(Lambda 的简化写法)

类型 语法 等价 Lambda
静态方法 ClassName::staticMethod args -> ClassName.staticMethod(args)
实例方法(任意对象) Type::instanceMethod (obj, args) -> obj.instanceMethod(args)
实例方法(特定对象) obj::instanceMethod args -> obj.instanceMethod(args)
构造器 ClassName::new args -> new ClassName(args)

示例:

// 静态方法
List<String> upper = names.stream()
    .map(String::toUpperCase) // 等价于 s -> s.toUpperCase()
    .collect(Collectors.toList());

// 构造器引用
List<PersonDTO> dtos = personList.stream()
    .map(PersonDTO::new) // 假设 PersonDTO 有 Person 构造器
    .collect(Collectors.toList());

✅ 四、并发与异步(CompletableFuture)

// 异步执行
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 模拟耗时操作
    return "Hello Async";
});

// 链式调用
future.thenApply(s -> s + " World")
      .thenAccept(System.out::println)
      .join(); // 阻塞等待结果

✅ 五、Optional 安全操作

Optional<Person> optional = Optional.ofNullable(getPerson());

// 如果存在则打印
optional.ifPresent(p -> System.out.println(p.getName()));

// 映射并避免空指针
String name = optional.map(Person::getName)
                      .orElse("Unknown");

✅ 六、自定义函数式接口

@FunctionalInterface
public interface Validator<T> {
    boolean validate(T t);
}

// 使用
Validator<String> notEmpty = s -> s != null && !s.trim().isEmpty();
boolean valid = notEmpty.validate("test");

⚠️ 注意事项

  1. 避免在 Lambda 中修改外部变量(只能访问 final 或 effectively final 变量)

    int x = 10;
    Runnable r = () -> {
        // x = 20; // ❌ 编译错误!
        System.out.println(x); // ✅ 可以读取
    };
    
  2. 慎用 parallelStream()
    并行流不一定更快,小数据集反而更慢,且需注意线程安全。

  3. 优先使用方法引用
    list.forEach(System.out::println)list.forEach(s -> System.out.println(s)) 更简洁。


✅ 总结:高频 Lambda 场景速查表

场景 代码模板
遍历集合 list.forEach(item -> ...)
过滤 list.stream().filter(x -> ...).collect(...)
转 Map list.stream().collect(toMap(k, v))
分组 list.stream().collect(groupingBy(...))
异步任务 CompletableFuture.supplyAsync(() -> ...)
安全取值 optional.map(...).orElse(...)
条件判断 Predicate<String> p = s -> s.length() > 0;

更多推荐