Java Optional介绍和用法

Java 的 Optional 是 Java 8 引入的一个容器类,旨在更优雅地处理可能为 null 的值,避免显式的 null 检查和空指针异常(NullPointerException)。它的核心思想是强制开发者明确处理“值可能不存在”的情况,而不是隐式忽略。

一、Optional 的核心作用

显式表示“值可能缺失”:通过类型系统提示调用者需要处理空值。

减少 null 检查代码:提供链式方法替代嵌套的 if (obj != null)

避免空指针异常:通过安全的方法访问潜在的空值。

二、创建 Optional 对象

// 1. 创建一个非空值的 Optional(若值为 null 会抛出 NPE)
Optional<String> optional1 = Optional.of("Hello");

// 2. 创建一个可能为 null 的 Optional
String value = getNullableValue(); // 可能返回 null
Optional<String> optional2 = Optional.ofNullable(value);

// 3. 创建一个空的 Optional
Optional<String> optional3 = Optional.empty();

三、Optional 的常用方法

1. 检查值是否存在
  • isPresent():判断值是否存在。

  • isEmpty()(Java 11+):判断值是否为空。

if (optional.isPresent()) {
    System.out.println("值存在: " + optional.get());
}

2. 值存在时执行操作
  • ifPresent(Consumer): 值存在时执行操作。

optional.ifPresent(v -> System.out.println("值为: " + v));

3. 获取值
  • get():直接获取值(若值为空会抛异常,需谨慎使用)。

  • orElse(T): 值存在时返回值,否则返回默认值。

  • orElseGet(Supplier): 延迟生成默认值。

  • orElseThrow(): 值不存在时抛出异常(可自定义异常)。

String result = optional.orElse("默认值");
String result = optional.orElseGet(() -> generateDefault());
String result = optional.orElseThrow(() -> new NotFoundException("值不存在"));

4. 链式操作
  • map(Function): 对值进行转换(若值为空,直接返回空 Optional)。

  • flatMap(Function): 与 map 类似,但用于返回 Optional 的函数。

  • filter(Predicate): 过滤值,不满足条件则返回空 Optional。

Optional<String> upperCase = optional.map(String::toUpperCase);
Optional<Integer> length = optional.flatMap(v -> Optional.of(v.length()));
Optional<String> filtered = optional.filter(v -> v.length() > 3);

四、使用场景

方法返回值:明确表示返回值可能为空。

public Optional<User> findUserById(int id) {
    // 查询数据库,可能返回 null
    return Optional.ofNullable(userRepository.findById(id));
}

链式处理可能为空的值

String city = userOptional
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("未知城市");

替代 if-else 嵌套

// 传统方式
if (user != null && user.getAddress() != null) {
    // ...
}

// Optional 方式
userOptional.flatMap(User::getAddress).ifPresent(address -> {
    // ...
});

五、最佳实践与注意事项

避免以下情况

        将 Optional 作为字段、方法参数或集合元素(违背设计初衷)。

        过度使用 Optional,导致代码冗余。

        直接调用 get() 而不检查是否存在值。

优先使用 orElse/orElseGet 替代 isPresent()

// 不推荐
if (optional.isPresent()) {
    return optional.get();
} else {
    return "default";
}

// 推荐
return optional.orElse("default");

与 Stream 结合使用

List<String> names = users.stream()
    .map(user -> user.getName().orElse("匿名"))
    .collect(Collectors.toList());

六、完整示例

public class OptionalDemo {
    public static void main(String[] args) {
        Optional<String> optional = Optional.ofNullable(getNullableString());

        String value = optional
            .map(String::toUpperCase)
            .filter(s -> s.length() > 3)
            .orElse("DEFAULT");

        System.out.println(value); // 输出 "DEFAULT" 或处理后的值
    }

    private static String getNullableString() {
        return Math.random() > 0.5 ? "hello" : null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CnLg.NJ

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值