Optional

java8 的 Optional

所属包:

package java.util;

Optional 就是一个容器

  • Optional 无法直接构造因为构造方法是私有的
    /**
     * Constructs an empty instance.
     *
     * @implNote Generally only one empty instance, {@link Optional#EMPTY},
     * should exist per VM.
     */
    private Optional() {
        this.value = null;
    }
  • 构造Optional方式有以下
    /**
     * Returns an empty {@code Optional} instance.  No value is present for this
     * Optional.
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

    /**
     * Returns an {@code Optional} with the specified present non-null value.
     *
     */
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

    /**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     *
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }


Optional使用

    public static void main(String[] args) {

        Employee employee = new Employee();
        employee.setName("zhangsan");

        Employee employee1 = new Employee();
        employee1.setName("lisi");

        Company company = new Company();
        company.setName("company1");

        List<Employee> employees = Arrays.asList(employee, employee1);
        company.setEmployees(employees);

        

        Optional<Company> optional = Optional.ofNullable(company);
        // 不推荐用法
        if (optional.isPresent()) {
            // ....
        }
        // 推荐用法
        System.out.println(optional.map(theCompany -> theCompany.getEmployees())
                .orElse(Collections.emptyList()));
        
    }
### Optional 的使用方法 `Optional` 是 Java 8 引入的一个容器类,用于处理可能为 `null` 的值,从而避免空指针异常(NullPointerException, NPE)。它提供了一系列方法来优雅地处理空值问题。 #### 创建 Optional 实例 - **`empty()`**:创建一个空的 `Optional` 实例,适用于值确实为空的情况。 - **`of(T value)`**:创建一个包含非空值的 `Optional` 实例。如果传入的值为 `null`,会抛出 `NullPointerException`。 - **`ofNullable(T value)`**:创建一个 `Optional` 实例,如果值为 `null`,则返回一个空的 `Optional`,而不是抛出异常 [^2]。 #### 获取值 - **`get()`**:返回 `Optional` 中包装的值。在调用前必须确保值存在,否则会抛出异常。 - **`isPresent()`**:判断 `Optional` 中是否有值,返回布尔值。 - **`ifPresent(Consumer<? super T> consumer)`**:如果值存在,则执行给定的消费者操作,否则不执行任何操作 [^1]。 #### 提供默认值或抛出异常 - **`orElse(T other)`**:返回 `Optional` 中包装的值,如果值不存在,则返回指定的默认值。 - **`orElseGet(Supplier<? extends T> other)`**:与 `orElse` 类似,但默认值是通过 `Supplier` 函数式接口提供的,只有在值不存在时才会计算。 - **`orElseThrow(Supplier<? extends X> exceptionSupplier)`**:返回 `Optional` 中的值,如果不存在,则抛出指定的异常 [^1]。 ### Optional 的最佳实践 #### 避免直接使用 `get()` 在没有确认 `Optional` 是否包含值的情况下,直接调用 `get()` 方法是非常危险的,因为它可能会抛出 `NoSuchElementException`。因此,在调用 `get()` 之前,应始终使用 `isPresent()` 或 `ifPresent()` 来检查值是否存在 。 #### 使用 `orElse` 和 `orElseGet` 提供默认值 当需要处理可能为空的情况时,`orElse` 和 `orElseGet` 是非常有用的工具。`orElseGet` 特别适合在默认值需要复杂计算时使用,因为它只在必要时才执行计算 [^1]。 #### 使用 `map` 和 `flatMap` 进行链式调用 `Optional` 支持 `map` 和 `flatMap` 方法,允许对值进行转换而不必显式地进行空值检查。例如,在处理嵌套对象时,可以使用 `flatMap` 来简化代码 [^3]。 #### 示例代码 ```java public Result<TaskInfoVo> getTaskInfo(String taskId) { TaskNode taskNode = taskExecutor.getByTaskId(taskId); TaskInfoVo taskInfoVo = TaskInfoVo.builder() .taskName(taskNode.getName()) .finishTime(Optional.ofNullable(taskNode.getFinishTime()) .map(date -> date.getTime()) .orElse(null)) .user(taskNode.getUser()) .memo(taskNode.getMemo()) .build(); return Result.ok(taskInfoVo); } ``` 在这个例子中,`Optional.ofNullable` 被用来处理 `taskNode.getFinishTime()` 可能为 `null` 的情况。通过 `map` 方法,可以安全地将日期转换为时间戳,而无需担心空指针异常 [^3]。 #### 减少 `if (obj == null)` 检查 通过合理使用 `Optional`,可以减少代码中大量的 `if (obj == null)` 检查,使代码更加简洁和易读。特别是在与外部世界(如数据库查询、REST 端点等)交互时,`Optional` 可以帮助更好地管理空值 [^4]。 #### 避免过度使用 `Optional` 尽管 `Optional` 提供了许多便利,但过度使用它也可能导致代码变得难以理解和维护。因此,在决定是否使用 `Optional` 时,应权衡其利弊,并确保团队成员都理解其用途和用法 [^1]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值