Java的Optional类——解决空指针异常的好工具

java.util.Optional 类是 Java 8 引入的一个容器对象,旨在解决空指针异常的问题。Optional 类提供了一种优雅的方式来处理可能为 null 的值,从而避免了显式的 null 检查。这对于提高代码的可读性和减少空指针异常非常有用。

Optional 类的基本用法

  1. 构造:不能直接使用 new Optional() 创建 Optional 对象,因为它的构造器是私有的。可以通过 Optional.of(T)Optional.ofNullable(T)Optional.empty() 方法来创建 Optional 对象。

    • Optional.of(T t):如果 t 不为 null,则创建一个包含 tOptional 对象;否则抛出 NullPointerException
    • Optional.ofNullable(T t):如果 t 不为 null,则创建一个包含 tOptional 对象;否则创建一个空的 Optional 对象。
    • Optional.empty():创建一个空的 Optional 对象。
  2. 判断是否为空:可以使用 Optional.isPresent() 方法来判断 Optional 对象是否包含非空值。

  3. 获取值:可以通过多种方式获取 Optional 包含的值:

    • Optional.get():如果 Optional 包含非空值,则返回该值;否则抛出 NoSuchElementException
    • Optional.orElse(T other):如果 Optional 包含非空值,则返回该值;否则返回提供的默认值 other
    • Optional.orElseGet(Supplier<T> other):如果 Optional 包含非空值,则返回该值;否则调用 Supplier 获取一个默认值。
    • Optional.orElseThrow(Supplier<? extends X> exceptionSupplier):如果 Optional 包含非空值,则返回该值;否则抛出由 exceptionSupplier 提供的异常。
  4. 转换:可以使用 Optional.map(Function<T, R> mapper)Optional.flatMap(Function<T, Optional<R>> mapper) 方法来转换 Optional 内部的值。

  5. 组合操作:可以使用 Optional.filter(Predicate<T> predicate) 方法来过滤 Optional 内部的值,还可以使用 Optional.ifPresent(Consumer<T> action) 方法来执行某些操作。

示例代码

下面是一些使用 Optional 的示例代码。

创建 Optional
String name = "John Doe";
Optional<String> optionalName = Optional.of(name); // 不会为 null
Optional<String> optionalNameOrNull = Optional.ofNullable(null); // 可以为 null
Optional<String> emptyOptional = Optional.empty(); // 空的 Optional
判断是否为空
if (optionalName.isPresent()) {
    System.out.println("Optional is present.");
} else {
    System.out.println("Optional is empty.");
}
获取值
// 如果 Optional 包含非空值则获取它,否则抛出 NoSuchElementException
String nameValue = optionalName.get();

// 如果 Optional 包含非空值则获取它,否则返回默认值 "Unknown"
String defaultName = optionalName.orElse("Unknown");

// 如果 Optional 包含非空值则获取它,否则调用 Supplier 获取默认值
String defaultNameFromSupplier = optionalName.orElseGet(() -> "Unknown");

// 如果 Optional 包含非空值则获取它,否则抛出 IllegalArgumentException
String nameOrThrow = optionalName.orElseThrow(IllegalArgumentException::new);
转换值

假设我们有一个 Person 类,它有一个 getName 方法。

class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Person person = new Person("Jane Smith");
Optional<Person> optionalPerson = Optional.of(person);

// 转换 Person 为 String
Optional<String> personName = optionalPerson.map(Person::getName);
personName.ifPresent(System.out::println); // 输出 "Jane Smith"

// 使用 flatMap 进行更复杂的转换
Optional<String> lastName = optionalPerson.flatMap(p -> Optional.of(p.getName().split(" "))).flatMap(Arrays::stream).findFirst();
lastName.ifPresent(System.out::println); // 输出 "Smith"
组合操作
// 过滤操作
Optional<String> filteredName = optionalName.filter(n -> n.startsWith("J"));
filteredName.ifPresent(System.out::println); // 输出 "John Doe"

// 执行操作
optionalName.ifPresent(System.out::println); // 输出 "John Doe"

完整示例

下面是一个完整的示例程序,它展示了如何使用 Optional 类来处理可能为 null 的值。

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        String name = "John Doe";
        Optional<String> optionalName = Optional.of(name);
        Optional<String> optionalNameOrNull = Optional.ofNullable(null);

        // 判断是否为空
        System.out.println(optionalName.isPresent()); // 输出 true
        System.out.println(optionalNameOrNull.isPresent()); // 输出 false

        // 获取值
        System.out.println(optionalName.get()); // 输出 "John Doe"
        System.out.println(optionalNameOrNull.orElse("Default Name")); // 输出 "Default Name"

        // 转换值
        Optional<String> upperCaseName = optionalName.map(String::toUpperCase);
        upperCaseName.ifPresent(System.out::println); // 输出 "JOHN DOE"

        // 组合操作
        optionalName.filter(s -> s.startsWith("J"))
                    .ifPresent(System.out::println); // 输出 "John Doe"
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

TracyCoder123

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值