函数式编程之 Optional
核心用途
Optional 是 Java 8 引入的容器类,用于解决 null` 检查的繁琐性和代码可读性问题。它明确表示一个值可能存在或可能不存在,通过链式调用强制开发者处理空值场景。
创建对象
| 方法 | 描述 | 示例 | 
|---|---|---|
| Optional.of(value) | 创建非空 Optional(若 value为 null 抛异常) | Optional.of(“Hello”) | 
| Optional.ofNullable(value) | 允许 value为 null的 Optional | Optional.ofNullable(nullableValue) | 
| Optional.empty() | 创建空 Optional | Optional.empty() | 
常用操作方法
判断值是否存在
Optional<String> opt = Optional.of("data");
if (opt.isPresent()) { // 值存在时的操作
}
 
消费值(ifPresent)
opt.ifPresent(value -> System.out.println("Value: " + value));
 
获取值
- get(): 直接获取值(若为空抛 NoSuchElementException)
 
String value = opt.get(); // 不推荐,容易引发异常
 
- orElse(default): 值不存在时返回默认值
 
String result = opt.orElse("default");
 
- orElseGet(supplier): 值不存在时通过 Supplier 生成默认值
 
String result = opt.orElseGet(() -> generateDefault());
 
- orElseThrow(exceptionSupplier): 值不存在时抛出自定义异常
 
String result = opt.orElseThrow(() -> new RuntimeException("Value not found"));
 
转换值(map 与 flatMap)
- map(Function): 对值进行转换(返回新 Optional)
 
Optional<Integer> lengthOpt = opt.map(String::length);
 
- flatMap(Function): 扁平化转换(避免嵌套 Optional)
 
Optional<U> result = opt.flatMap(value -> anotherOptional);
 
过滤值(filter)
Optional<String> filtered = opt.filter(s -> s.length() > 3);
 
链式调用实战
传统写法(多层嵌套 if):
if (user != null) {Address address = user.getAddress();if (address != null) {String city = address.getCity();if (city != null) {System.out.println(city.toUpperCase());}}
}
 
Optional 链式调用:
Optional.ofNullable(user).map(User::getAddress).map(Address::getCity).map(String::toUpperCase).ifPresent(System.out::println);
 
处理嵌套 Optional
问题场景:
当方法返回 Optional<Optional> 时,需要扁平化处理。
Optional<Optional<String>> nestedOpt = Optional.of(Optional.of("data"));
 
解决方案:
使用 flatMap 代替 map:
String result = nestedOpt.flatMap(Function.identity()).orElse("default");
 
注意事项
- 不要滥用 Optional: 
- 避免将 Optional 作为方法参数或类的字段(设计为返回类型)。
 - 不要用 Optional 替代所有 null 检查,仅在需要明确表达“可能无值”时使用。
 
 - 避免 get():
尽量使用 orElse、orElseGet 或 orElseThrow 代替直接 get()。 - 性能考量:
Optional 的链式调用会创建中间对象,但对大多数应用场景性能影响可忽略。 - 与 null 的互操作:
 
Object value = optional.orElse(null); // 不推荐,但必要时可用
 
完整示例
import java.util.Optional;public class OptionalDemo {public static void main(String[] args) {// 示例:用户信息处理User user = findUserById("123");String city = Optional.ofNullable(user).flatMap(User::getAddress).map(Address::getCity).filter(c -> !c.isEmpty()).orElse("Unknown City");System.out.println(city);}static User findUserById(String id) {// 模拟数据库查询return new User(new Address("Beijing"));}static class User {private Address address;User(Address address) { this.address = address; }Optional<Address> getAddress() { return Optional.ofNullable(address); }}static class Address {private String city;Address(String city) { this.city = city; }String getCity() { return city; }}
}
 
通过合理使用 Optional,可以显著提升代码的可读性和健壮性,减少 NullPointerException 的风险。
