Optional详解和常用API

目录

一、Optional简介

二、构建Optional对象三种方式

[2.1 Optional.of(value)](#2.1 Optional.of(value))

[2.1.1 使用案例](#2.1.1 使用案例)

[2.2 Optional.ofNullable(value)](#2.2 Optional.ofNullable(value))

[2.2.1 使用案例](#2.2.1 使用案例)

[2.3 Optional.empty()](#2.3 Optional.empty())

[2.3.1 使用案例](#2.3.1 使用案例)

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

[3.1 isPresent](#3.1 isPresent)

[3.1.1 使用案例](#3.1.1 使用案例)

[3.2 ifPresent](#3.2 ifPresent)

[3.2.1 使用案例](#3.2.1 使用案例)

[3.3 orElse](#3.3 orElse)

[3.3.1 使用案例](#3.3.1 使用案例)

[3.4 orElseGet](#3.4 orElseGet)

[3.4.1 使用案例](#3.4.1 使用案例)

[3.4.2 orElse和orElseGet的区别](#3.4.2 orElse和orElseGet的区别)

[3.5 orElseThrow](#3.5 orElseThrow)

[3.5.1 使用案例](#3.5.1 使用案例)

[3.6 map](#3.6 map)

[3.6.1 使用案例](#3.6.1 使用案例)

[3.7 filter](#3.7 filter)

[3.7.1 使用案例](#3.7.1 使用案例)

[3.8 or](#3.8 or)

[3.8.1 使用案例](#3.8.1 使用案例)

[3.9 stream](#3.9 stream)

[3.9.1 使用案例](#3.9.1 使用案例)


一、Optional简介

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

优点

1、清晰的表明变量值

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

3、提高了代码的强壮型

缺点

1、代码过于冗长

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

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

二、构建Optional对象三种方式

2.1 Optional.of(value)

java 复制代码
   /**
     * 返回一个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 使用案例

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

2.2 Optional.ofNullable(value)

java 复制代码
/**
  * 返回一个描述给定值的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 使用案例

java 复制代码
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()

java 复制代码
  /**
     * 返回一个空的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 使用案例

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

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

3.1 isPresent

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

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

3.1.1 使用案例

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

3.2 ifPresent

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

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

3.2.1 使用案例

java 复制代码
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方法传入的值

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

3.3.1 使用案例

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

3.4 orElseGet

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

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

3.4.1 使用案例

java 复制代码
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的区别

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

3.5 orElseThrow

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

java 复制代码
/**
 * 如果存在值,则返回该值,否则抛出由异常函数提供的异常
 * 参数: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 使用案例

java 复制代码
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操作

java 复制代码
/**
 * 如果存在值,则返回一个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 使用案例

java 复制代码
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。

java 复制代码
/**
 * 如果存在一个值,并且该值与给定的值匹配,则返回秒速该值的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 使用案例

java 复制代码
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

java 复制代码
/**
 * 如果存在值时,返回一个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 使用案例

java 复制代码
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())

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

3.9.1 使用案例

java 复制代码
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_脚本之家

相关推荐
hopetomorrow13 分钟前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
不是二师兄的八戒22 分钟前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php
小牛itbull23 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i31 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
闲暇部落34 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
爱编程的小生34 分钟前
Easyexcel(2-文件读取)
java·excel
GIS瞧葩菜43 分钟前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
chnming19871 小时前
STL关联式容器之set
开发语言·c++
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔1 小时前
《线性代数的本质》
线性代数·算法·决策树