当前位置:首页>java>Java 新特性基础:代码看懂:Lambda、Stream、Optional、方法引用

Java 新特性基础:代码看懂:Lambda、Stream、Optional、方法引用

  • 2026-10-21 13:27:21
Java 新特性基础:代码看懂:Lambda、Stream、Optional、方法引用
一、Lambda 表达式:把无关结构去掉

1. 传统写法(结构多,重点被淹没)

// 创建并启动一个线程new Thread(new Runnable() {// Runnable 接口只有一个方法 run@Overridepublicvoidrun() {// 真正有用的逻辑其实只有这一行        System.out.println("do work");    }}).start();

问题:

  • Runnable、run()、@Override 都是结构

  • 真正关心的业务被包在最里面


2. Lambda 写法(只保留有用信息)

// () 表示没有参数// -> 后面就是 run 方法的实现new Thread(() -> {    System.out.println("do work");}).start();

如果只有一行逻辑:

// 单行 Lambda 可以省略大括号new Thread(() -> System.out.println("do work")).start();

二、Stream API:把 for 循环拆成“步骤”

1. 传统 for 循环(多件事混在一起)

List<String> names = new ArrayList<>();for (User user : users) {// 判断条件    if (user.getAge() > 18) {// 数据转换        names.add(user.getName());    }}

读这段代码时,你需要在脑子里“拆逻辑”。


2. Stream 写法(一步一行)

List<String> names = users.stream()          // 1. 从集合创建数据流        .filter(user -> user.getAge() > 18)  // 2. 只保留年龄大于 18 的用户        .map(User::getName)                  // 3. 把 User 转换成 name        .collect(Collectors.toList());       // 4. 把结果收集成 List

每一行只做一件事,
逻辑顺序非常清晰。


3. 常见 Stream 实战代码

求和

int total = orders.stream()                  // 获取订单集合流        .mapToInt(Order::getAmount)          // 把订单转换成金额 int        .sum();                              // 对所有金额求和

分组

Map<String, List<User>> groupMap =        users.stream()                       // 用户集合             .collect(                 Collectors.groupingBy(                     User::getDept           // 按部门分组                 )             );

去重

List<String> list = data.stream()             // 原始数据流        .distinct()                           // 去重(依赖 equals)        .collect(Collectors.toList());        // 转成 List

三、Optional:让“可能为空”变得明显

1. 传统写法(容易漏判断)

User user = getUser();if(user != null) {   System.out.println(user.getName());}

这种写法的问题在于:
null 判断容易被遗漏。


2. Optional 写法(强制你处理空值)

Optional<User> optionalUser = getUserOptional();// 如果有值,才执行 Lambda 里的逻辑optionalUser.ifPresent(user -> {    System.out.println(user.getName());});

从变量名就能看出来:
这个值可能为空。


3. 提供默认值

// 如果 optional 里有值,直接返回// 如果没有值,返回 new User()User user = optionalUser.orElse(new User());

或者懒加载:

// 只有在 optional 为空时,才会执行 User::newUser user = optionalUser.orElseGet(User::new);

4. 不推荐的用法

// 如果 optional 为空,这里直接抛异常User user = optionalUser.get();

这种写法违背了 Optional 的设计初衷。


四、方法引用:给 Lambda 再减一层

1. 普通 Lambda

users.stream()     .map(user -> user.getName())             // 从 User 中取 name     .forEach(name -> System.out.println(name));

2. 方法引用写法

users.stream()     .map(User::getName)                      // 等价于 user -> user.getName()     .forEach(System.out::println);           // 等价于 name -> System.out.println(name)

方法引用只是 Lambda 的简写形式。


3. 常见方法引用类型

User::getName          // 类名::实例方法System.out::println   // 对象::实例方法Math::abs             // 类名::静态方法

五、在项目中的“安全使用原则”

这是我在项目里长期用下来的经验:

// 逻辑简单,使用 Streamusers.stream()     .filter(...)     .map(...)     .collect(...);// 逻辑复杂,老老实实用 forfor (...) {    ...}

规则只有一个:

代码是给人看的,不是给编译器看的。


写在最后

Lambda、Stream、Optional
并没有让 Java “更难”,
只是让你:

  • 少写模板代码

  • 把注意力放在真正的逻辑上

最新文章

随机文章