optional

参考资料:

Java8 Optional用法和最佳实践 - 掘金

一、背景

根据Oracle文档,Optional是一个容器对象,可以包含也可以不包含非null值。Optional在Java 8中引入,目的是解决  NullPointerExceptions的问题。本质上,Optional是一个包装器类,其中包含对其他对象的引用。在这种情况下,对象只是指向内存位置的指针,并且也可以指向任何内容。从其它角度看,Optional提供一种类型级解决方案来表示可选值而不是空引用。

Optional之前

在Java 8之前,程序员将返回null而不是Optional。这种方法有一些缺点。一种是没有明确的方法来表示null可能是一个特殊值。相比之下,在API中返回Optional是明确的声明,其中可能没有值。如果我们要确保不会出现空指针异常,则需要对每个引用进行显式的空检查,如下所示,我们都同意这是很多样板。

// Life before Optional
    private void getIsoCode( User user){
        if (user != null) {
            Address address = user.getAddress();
            if (address != null) {
                Country country = address.getCountry();
                if (country != null) {
                    String isocode = country.getIsocode();
                    if (isocode != null) {
                        isocode = isocode.toUpperCase();
                    }
                }
            }
        }
    }

为了避免上述繁杂 的  !=null  ,我们可以引入Optional

二、Optional类的对象创建

均为静态方法创建

1. Optional.empty()

optional_第1张图片

 //第一种创建方式
        Optional optional=Optional.empty();
        //判断是否为空. 此时为 空null,
        System.out.println(optional.isEmpty());
        //判断是否存在。此时不存在,返回false
        System.out.println(optional.isPresent());
        //如果optional为null,则会出现异常.  
        System.out.println(optional.get());

2.Optional.of()

optional_第2张图片

optional_第3张图片

//第二种创建方式
        //Optional optional=Optional.of(null); //value 不能为null,不然会报错
        Optional optional1=Optional.of("123");
        System.out.println(optional1.get());

3. Optional.ofNullable()

optional_第4张图片

三、检查Optional的value是否存在

下面代码中包含了3种判断方法

   Optional optional=Optional.ofNullable(null);
        //1.
        boolean empty = optional.isEmpty();
        //2.
        boolean present = optional.isPresent();
        //3.
        optional.ifPresent(new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println("一旦存在,就调用我这个方法");
            }
        });

这个filter方法,有点意思,可以自己去判断是否满足一个条件,满足则创建一个新的Optional对象并且value跟所要判断的optional的value一致。否则返回一个Optional.empty()

optional_第5张图片

四、获取value的方法

optional_第6张图片

让gpt解释一下  orElse() 与orElseGet()的区别

optional_第7张图片

五、Optional的最佳实践

当你在编写项目时使用 Optional 类型时,以下是一些最佳实践建议:

  1. 不要将 Optional 用于方法参数或字段类型

    • Optional 类型主要用于表示可能存在空值的返回值类型。
    • 如果将其用于方法参数或字段类型,则可能会使代码变得复杂,甚至不必要。
  2. 尽量避免使用 Optional 的 get() 方法

    • Optional 的 get() 方法可以用于获取 Optional 对象中的值,但如果 Optional 对象为空,则会抛出 NoSuchElementException 异常。
    • 因此,为了避免异常的发生,最好使用其他方法来处理 Optional 对象的值,比如 orElse() 或 orElseGet()。
  3. 使用 Optional 来处理返回值为空的情况

    • 如果一个方法可能返回 null,应该考虑使用 Optional 类型来代替。
    • 这样可以更明确地表示空值的含义,并提供更加优雅的语法来处理空值的情况。
  4. 使用 Optional 与 Stream API 结合使用

    • Optional 和 Stream API 是 Java 8 中引入的两个重要特性。
    • 它们结合使用可以提高代码的可读性和简洁性。
    • 可以使用 Optional 的 filter() 和 map() 方法来对 Stream 进行过滤和转换操作,从而生成新的 Optional 对象。

// 示例 1:使用 Optional 来处理返回值为空的情况
public Optional getOptionalValue(String key) {
    String value = getValueByKey(key);
    return Optional.ofNullable(value);
}

// 示例 2:使用 Optional 和 Stream API 进行过滤操作
public Optional findUserByName(String name) {
    List userList = getUserList();
    return userList.stream()
            .filter(user -> user.getName().equals(name))
            .findFirst();
}

// 示例 3:使用 orElse() 方法提供默认值
Optional optional = Optional.empty();
String result = optional.orElse("default value");

// 示例 4:使用 orElseGet() 方法提供默认值
Optional optional = Optional.empty();
String result = optional.orElseGet(() -> generateDefaultValue());

// 示例 5:使用 map() 方法将 Optional 对象中的值转换为其他类型
Optional optional = Optional.of("hello");
Optional lengthOptional = optional.map(String::length);

// 示例 6:使用 flatMap() 方法展开 Optional 对象
Optional> optional = Optional.of(Optional.of("hello"));
Optional flattenedOptional = optional.flatMap(Function.identity());

关于示例6的一些解释:

optional_第8张图片

你可能感兴趣的:(JAVA,java)