Java 8新特性之 Optional 类

前言

java.util.Optional 是java8中引进的一个新的类,我们通过Optional类的源码可以看到,该方法的作用可以对可能缺失的值进行建模,而不是直接将null赋值给变量。

Optional类产生背景

作为java开发者,业务逻辑中需要经常检查对象是否为空,因此业务中会产生大量的if else 结构和判断对象是否为空的方法(已经有很多判断对象是否为空的方法 例如: StringUtils,Objects,CollectionUtils等工具类)。为了代码的可读性和可维护性,Optional类应运而生。

Optional类API

1: static Optional empty() 返回空的 Optional 实例。

/**
 * Returns an empty {@code Optional} instance.  No value is present for this
 * Optional.
 * @return an empty {@code Optional}
 */
public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}

2: Optional filter(Predicate<? super predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional

/**
 * If a value is present, and the value matches the given predicate,
 * return an {@code Optional} describing the value, otherwise return an
 * empty {@code Optional}.
 */
public Optional<T> filter(Predicate<? super T> predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent())
        return this;
    else
        return predicate.test(value) ? this : empty();
}

3: Optional flatMap(Function<? super T,Optional> mapper) 如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional

/**
 * If a value is present, apply the provided {@code Optional}-bearing
 * mapping function to it, return that result, otherwise return an empty
 */
public<R> Optional<R> flatMap(Function<? super T, Optional<R>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}

4:T get() 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException

/**
 * If a value is present in this {@code Optional}, returns the value,
 * otherwise throws {@code NoSuchElementException}.
 */
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

5: void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情。

/**
 * If a value is present, invoke the specified consumer with the value,
 * otherwise do nothing.
 *
 * @throws NullPointerException if value is present and {@code consumer} is
 * null
 */
public void ifPresent(Consumer<? super T> consumer) {
    if (value != null)
        consumer.accept(value);
}

6: boolean isPresent() 如果值存在则方法会返回true,否则返回 false

/**
 * Return {@code true} if there is a value present, otherwise {@code false}.
 *
 * @return {@code true} if there is a value present, otherwise {@code false}
 */
public boolean isPresent() {
    return value != null;
}

7: Optional map(Function<? super T,? extends R> mapper) 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional

/**
 * If a value is present, apply the provided mapping function to it,
 * and if the result is non-null, return an {@code Optional} describing the
 * result.  Otherwise return an empty {@code Optional}.
 *
 * @apiNote This method supports post-processing on optional values, without
 * the need to explicitly check for a return status.  For example, the
 * following code traverses a stream of file names, selects one that has
 * not yet been processed, and then opens that file, returning an
 * {@code Optional<FileInputStream>}:
 *
 * <pre>{@code
 *     Optional<FileInputStream> fis =
 *         names.stream().filter(name -> !isProcessedYet(name))
 *                       .findFirst()
 *                       .map(name -> new FileInputStream(name));
 * }</pre>
 *
 * Here, {@code findFirst} returns an {@code Optional<String>}, and then
 * {@code map} returns an {@code Optional<FileInputStream>} for the desired
 * file if one exists.
 */
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}

8: static Optional of(T value) 返回一个指定非null值的Optional。

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

9: static Optional ofNullable(T value) 如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional

/**
 * 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);
}

10: T orElse(T other) 如果存在该值,返回值, 否则返回 other

/**
 * Return the value if present, otherwise return {@code other}.
 *
 * @param other the value to be returned if there is no value present, may
 * be null
 * @return the value, if present, otherwise {@code other}
 */
public T orElse(T other) {
    return value != null ? value : other;
}

11: T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。

/**
 * Return the value if present, otherwise invoke {@code other} and return
 * the result of that invocation.
 */
public T orElseGet(Supplier<? extends T> other) {
    return value != null ? value : other.get();
}

12: T orElseThrow(Supplier<? extends X> exceptionSupplier)

如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常

/**
 * Return the contained value, if present, otherwise throw an exception
 * to be created by the provided supplier.
 *
 * @apiNote A method reference to the exception constructor with an empty
 * argument list can be used as the supplier. For example,
 * {@code IllegalStateException::new}
 */
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

Optional类使用

1: 判断方法返回值

public class OptionalTest {
    public static void main(String[] args) {
        Optional<User> user = Optional.of(getUser());
        if (user.isPresent()) {
            //执行其他代码
        }
    }

    public static User getUser() {
       return new User();
    }

}

2: 判断方法参数值

public static List<User> getUsers(Params params) {
    //判断参数params是否为空,并取OrganizationId的值
    String organizationId = Optional.ofNullable(params).map(Params::getOrganizationId).orElse(null);
    List<User> users = new ArrayList<>();
    users.add(new User());
    return users;
}

除了上面常用的方法 还有一些API根据自己的需求进行组装,满足自己的业务逻辑。

Optional工具类

// 判断List是否为空
public <T> Stream<T> ofNullable(Iterable<T> target) {
    if (target != null) {
        return Lists.newArrayList(target).stream();
    } else {
        return empty();
    }
}
//过滤List中null的元素
public <T> List<T> filterNullElem(Iterable<T> target) {
    return ofNullable(target).filter(Objects::nonNull).collect(Collectors.toList());
}

总结

上面介绍了Optional类的API方法和常见用法。这些方法是最原始的方法,可以根据自己的业务开发场景,封装适合自己的工具类,方便快速开发。文章中如有错误之处 请不吝赐教,谢谢读者阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Java8中的Optional是一个容器对象,可以包含null或非null值。它提供了一种优雅的方式来处理null值,避免了NullPointerException异常的出现。Optional可以用于返回值、方法参数和实例变量等场景中,使代码更加简洁、清晰和安全。使用Optional可以使代码更加健壮,减少了代码中的null检查和异常处理,提高了代码的可读性和可维护性。 ### 回答2: OptionalJava 8中新引入的一个,它的主要作用是在避免NullPointerException的情况下将null值返回给调用者。这个是一个容器对象,它可以保存非空的对象,也可以保存空值(null)。 Optional提供了通过判断一个对象是否为空来避免空指针异常的方式。它可以在代码中替换传统的null判断,这样可以更加方便地编写代码,并且可以使代码更加健壮。 在Java中,如果一个方法返回值为null,那么在调用该方法返回值的时候,会有可能抛出NullPointerException异常。而Optional的出现可以帮助我们避免这种情况的出现,在调用Optional的get()方法时,如果Optional中保存的对象不为null,就会返回该对象,否则抛出一个NoSuchElementException异常。 Optional还提供了一些方法来简化代码,比如orElse()方法,如果Optional中保存的对象不为null,则返回该对象,否则返回指定的default值。还有ifPresent()方法,当Optional中保存的对象不为null时,会执行指定的代码,否则不执行。 总之,OptionalJava 8中一个很有用的,它可以帮助我们更加方便地处理null值,避免空指针异常的出现,并且可以简化代码。但是需要注意的是,不应该滥用Optional,因为它并不是完美的解决方案,有时候需要对null值进行特殊处理。 ### 回答3: Java 8在语言层面上增加了一个新的Optional。这是一个特殊的容器对象,可以包含一个null或非null的值。 Optional的目的是解决Java中的null引用问题。在Java中,如果一个变量被赋值为null,而我们试图调用该变量所对应的方法,那么就会出现NullPointerException异常。 使用Optional可以避免这种情况的发生。如果一个变量是Optional对象,那么我们必须显式地检查该对象是否包含非null的值,才能对其进行操作。这样,在我们试图调用该变量所对应的方法之前,就可以避免空指针异常的发生。 Optional提供了很多方法来判断是否有值、获取值、如果没有值则返回默认值等等,使得我们可以更加方便地处理空值。 下面是一些Optional提供的方法: 1. Optional.of(T value):创建一个包含非null值的Optional对象,如果T为null,则抛出NullPointerException异常。 2. Optional.ofNullable(T value):创建一个Optional对象,如果T为null,则该对象为空。 3. Optional.empty():创建一个空的Optional对象。 4. get():如果值存在,则返回该值,否则抛出异常。 5. orElse(T other):如果值存在,则返回该值,否则返回其他默认值。 6. isPresent():返回一个boolean型的值,表示该Optional对象是否包含值。 7. ifPresent(Consumer<? super T> consumer):如果该Optional对象包含值,则对该值执行给定的操作。 在编写Java程序时,我们应该始终努力避免使用null值。使用Optional,可以使得我们的代码更加健壮、可读性更强。但是,过多地使用Optional可能会导致代码过于冗长,所以在使用的过程中需要权衡利弊。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大伟攀高峰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值