当前位置: 首页 > news >正文

Optional详解和常用API

目录

一、Optional简介

二、构建Optional对象三种方式

2.1 Optional.of(value)

 2.1.1 使用案例

2.2 Optional.ofNullable(value)

2.2.1 使用案例

2.3 Optional.empty()

2.3.1 使用案例

三、Optional常用的api解析和使用案例

3.1 isPresent

 3.1.1 使用案例

 3.2 ifPresent

3.2.1 使用案例 

3.3 orElse

3.3.1 使用案例

3.4 orElseGet

3.4.1 使用案例

3.4.2 orElse和orElseGet的区别

3.5 orElseThrow

3.5.1 使用案例

3.6 map

3.6.1 使用案例

3.7 filter

3.7.1 使用案例

3.8 or

3.8.1 使用案例

3.9 stream

3.9.1 使用案例


一、Optional简介

Optional是java1.8引入的容器对象,它提供了非常丰富的API,主要是用于解决空指针异常的问题。

优点

1、清晰的表明变量值

2、丰富的API,增加了对空指针明确处理逻辑

3、提高了代码的强壮型

缺点

1、代码过于冗长

2、逻辑性不明显,代码易读性降低

3、引入了多一个对象的开销

二、构建Optional对象三种方式

2.1 Optional.of(value)

   /**
     * 返回一个Optional给定的非null值
     * @param <T>  值类型
     * @param value 描述的值,必须是非null
     * @return 返回Optional对象
     * @throws 如果value为空,抛出空指针异常
     */
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

 2.1.1 使用案例

Optional<String> optional = Optional.of("hello optional");
System.out.println(optional.get()); //输出hello optional

2.2 Optional.ofNullable(value)

/**
  * 返回一个描述给定值的Optional,如果不为null,则返回一个有值的Optional对象
  * @param <T>  值类型
  * @param value 描述的值,可能为null
  * @return 返回Optional对象,如果值为null,就返回一个null的Optional对象
  */
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
}

2.2.1 使用案例

Optional<String> optional11 = Optional.ofNullable("hello optional222");
Optional<String> optional2 = Optional.ofNullable(null);
System.out.println("optional12:"+optional11.get());//输出hello optional222
System.out.println("optional1:"+optional2.get());//抛出.NoSuchElementException异常,不存在任何值

2.3 Optional.empty()

  /**
     * 返回一个空的Optional实例,此Optional没有值
     * @param <T> 不存在的类型值
     * @return 返回一个空的Optional
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

2.3.1 使用案例

Optional<String> optional3 = Optional.empty();
System.out.println(optional2.get());//抛出.NoSuchElementException异常,不存在任何值

三、Optional常用的api解析和使用案例

3.1 isPresent

含义:判断Optional对象是否包含非空值 

/**
 * 如果存在值就返回true,如果不存在就返回false
 */
public boolean isPresent() {
        return value != null;
}

 3.1.1 使用案例

Optional<String> optional = Optional.of("hello optional");
if(optional.isPresent()){
   System.out.println("当前的option不为空,输出为:"+optional.get()); //输出hello optional
}

 3.2 ifPresent

如果Optional非空值,则执行传入操作

 /**
  * 如果Optional对象存在值,则执行给定的操作,否则不执行任何操作  
  */
public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
}

3.2.1 使用案例 

Optional<String> optional11 = Optional.ofNullable("hello optional222");
String str = "string string";
optional11.ifPresent(o -> System.out.println(str));//输出string string

3.3 orElse

如果Optional有值就将其返回,否则返回orElse方法传入的值

/**
 * 如果存在值,则返回该值,否则返回other
 * 参数:可以为任意值,也可以为null
 */
public T orElse(T other) {
  return value != null ? value : other;
}

3.3.1 使用案例

String s = null;
String optionStr = Optional.ofNullable(s).orElse("java");
System.out.println("optionStr:"+optionStr); //optionStr为空所以输出java

3.4 orElseGet

如果Optional有值,则将其返回,如果Optional没有值的时候,返回从该Supplier获得的值

/**
 * 如果存在值,则返回该值,否则返回由函数提供的结果
 * 参数:需要返回的函数
 */
public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
}

3.4.1 使用案例

class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public static void main(String[] args) {
    User user = null;
    user = Optional.ofNullable(user).orElseGet(()->{
         User user1 = new User();
         user1.setName("java");
         return user1;
     });
    System.out.println("user:"+user.getName()); //输出 user:java
}

3.4.2 orElse和orElseGet的区别

orElseorElseGet不同之处在于当ofNullable()传入的参数不为null时,orElse方法仍然创建了other这个对象。与之相反,orElseGet方法不创建对象。在执行密度调佣时,比如web服务或者数据查询,这个差异会对性能产生重大影响。而且我们还可以在orElseGet方法中加一些日志,可以把这种为空的情况给暴露出来,所以orElseorElseGet比起来,orElseGet性能和效率都比orElse要强。

3.5 orElseThrow

如果存在则返回该值,否则为空的话可以抛出自定义异常

/**
 * 如果存在值,则返回该值,否则抛出由异常函数提供的异常
 * 参数:exceptionSupplier 产生要抛出异常的提供函数
 * 参数类型:X-引发的异常
 * 抛出:如果不存在任何值,抛出NullPointerException,如果不存在任何值并且异常函数提供为null
 * 注意点:带有空参数列表的对异常构造函数的方法引用可用作提供者
 */
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
}

3.5.1 使用案例

class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public static void main(String[] args) {
  User user = new User();
  user.setName("java");
  User user1 = Optional.ofNullable(user).orElseThrow(()->{
      return new RuntimeException(); //因为user有值,所以不会抛出异常
  });
  System.out.println("user1:"+user1.getName()); // 输出user1:java
  user = null;
   User user2 = Optional.ofNullable(user).orElseThrow(()->{
       return new RuntimeException(); //因为user为空,抛出需要返回的异常,这里为运行时异常
   });

}

3.6 map

如果当前为Optional.empty,则依旧返回Optional.empty;否则返回一个新的Optional,该Optional函数包含的是:函数mapper在以value作为输入时的输出值,而且我们可以多次使用mapper操作 

/**
 * 如果存在值,则返回一个Optional,将给定映射函数应用于该值的结果,否则返回一个空的Optional
 * 如果映射函数返回null结果,则此方法返回空的Optional
 */
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));
        }
}

3.6.1 使用案例

class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public static void main(String[] args) {
    User user = new User();
    user.setName("java");
    Optional<String> optionalUser = Optional.ofNullable(user).map(User::getName);
    System.out.println(optionalUser.get());// 输出 java
}

3.7 filter

接受一个Predicate来对Optional中包含的值进行过滤,如果包含中的值满足条件,那么还是返回这个Optional,否则就返回Optional.empty。

/**
 * 如果存在一个值,并且该值与给定的值匹配,则返回秒速该值的Optional,否则返回一个空的Optional
 */
public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
}

3.7.1 使用案例

public static void main(String[] args) {
    User user = new User();
    user.setName("java");
    Optional<String> optionalUser = Optional.ofNullable(user).filter(o->o.getName().equals("java")).map(User::getName);
    if(optionalUser.isPresent()){
         System.out.println(optionalUser.get());// 输出 java
    }else{
          System.out.println("Optiaon为空");
    }
}

3.8 or

or方法是只有在java11已上才有

如果一个Optional包含值,则返回自己,否则返回由参数supplier获得的Optional

/**
 * 如果存在值时,返回一个Optional描述的值,否则将返回一个Optional产生通过供给的功能
 * 参数:供应商-产生要返回的Optional的供应功能
 * 返回值:如果一个值存在,返回一个Optional描述此值的Optional,否则Optional所生产的供应功能
 * 抛出:NullpointerException如果提供函数的null或产生的null结果
 */ 
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
        Objects.requireNonNull(supplier);
        if (isPresent()) {
            return this;
        } else {
            @SuppressWarnings("unchecked")
            Optional<T> r = (Optional<T>) supplier.get();
            return Objects.requireNonNull(r);
        }
    }

3.8.1 使用案例

public static void main(String[] args) {
   User user = null;
   Optional<User> optionalUser = Optional.ofNullable(user).or(() -> {
      User user1 = new User();
      user1.setName("java");
      return Optional.of(user1);
    });
    if (optionalUser.isPresent()) {
        System.out.println(optionalUser.get().getName()); //输出 java
    } else {
        System.out.println("为空");
    }
}

3.9 stream

stream方法是只有在java11已上才有 

将Optional转为一个Stream,如果Optional中包含值,那么就返回这个值的Stream,否则就返回一个空的Stream(Stream.empty())

/**
 * 如果存在值,则返回仅包含该值的顺序Stream,否则返回一个空的Stream
 * 返回值:Stream
 */
public Stream<T> stream() {
        if (!isPresent()) {
            return Stream.empty();
        } else {
            return Stream.of(value);
        }
}

3.9.1 使用案例

public static void main(String[] args) {
  User user = new User();
  user.setName("java");
  Stream<User> userStream = Optional.ofNullable(user).stream().filter(u->u.getName().equals("java"));
  userStream.forEach(u->{
       System.out.println(u.getName());
  });
}

参考文档:java中Optional的使用详细解析_java_脚本之家

相关文章:

  • 对LitJson开源插件的自定义尝试
  • EasyExcel文件导出,出现有文件但没有数据的问题
  • 揭开 Docker 容器的神秘面纱:深入理解容器原理
  • 【网络安全】【深度学习】【入侵检测】SDN模拟网络入侵攻击并检测,实时检测,深度学习【二】
  • JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB)
  • 【双系统 安装ADB】
  • Oracle中select取值后的字符串处理
  • 跨服务器迁移 Redis 数据
  • Web前端开发12章:深入探索与实战解析
  • 在不使用js在情况下只用css实现瀑布流效果
  • Java项目之消息队列(手写java模拟实现mq)【七、⽹络通信协议设计、消息队列服务器端实现、客户端实现】✔ ★
  • Oracle复习部分记录
  • AWS无服务器 应用程序开发—第八章 计算服务(AWS Lambda)
  • 【禁用Windows Defender】Defender Control v2.1
  • 前端HTML相关知识
  • adb简单使用命令
  • 【泛微系统】PC端/移动端JS写法区别
  • 深入理解Java正则表达式及其应用
  • Zig标准库:最全数据结构深度解析(1)
  • 【C++】C/C++内存管理
  • 今年五一档电影票房已破7亿
  • 申活观察|精致精准精细,城市“双面镜”照见怎样的海派活力
  • 几天洗一次头发最好?终于有答案了...
  • 2025年五一档电影新片票房破3亿
  • 孙一凡的东欧狂想音乐会:一场穿越东欧的听觉绮梦
  • 阿根廷发生5.6级地震,震源深度30公里