# Optional

# 概述

我们在编写代码会经常遇到空指针异常,所以在很多情况下我们需要各种非空判断

1
2
3
4
5
6
7
8
Author author = getAuthor();
if(author!=null){
System.out.println(author.getName());
}
Author author = getAuthor();
if(author!=null){
System.out.println(author.getName());
}

  • 对象属性也是对象的话会更多

  • JDK8 引入 Opitional,可以写出更好的代码来避免空指针异常。

  • 很多函数式编程相关 Api 会用到 Optional

# 使用

1
2
3
4
public Author getAuthor() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return author;
}

# 传统使用

1
2
3
4
Author author = getAuthors();
if (author != null) {
System.out.println(author.getName());
}

# Optional

Optional 的静态方法 ofNullable(T value) 将数据封装成一个 Optional 对象,传入参数为空也没问题

1
2
3
4
//源码
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}

1
2
Optional<Author> optionalAuthor = Optional.ofNullable(author)
optionalAuthor.ifPresent(author1 -> System.out.println(author1.getName()));

也可以使用方法直接返回 Optional 的值

1
2
3
4
5
6
7
8
9
10
11
public Optional<Author> getAuthor() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return Optional.ofNullable(author);
}
@Test
public void testOp(){
Optional<Author> optionalAuthor = getAuthor();
optionalAuthor.ifPresent(author1 -> System.out
.println(author1.getName()));
}

实际开发中,很多数据是从数据库获取,Mybatis3.5 版本已经支持 Optional 了,可以直接把 dao 层方法返回 值 类型定义成 Optional 类型 ,Mybatis 会自动将数据封装成对象后返回,封装的过程中不需要自己操作。

# 安全消费值

调用 Optional 对象的 ifPresent() 方法,参数类型 Consumer<? super T> 可以使用 Lambda 表达式。

# 安全获取值

安全的获取值应当避免使用 get () 方法而是使用以下两种方法 :

  1. orElseGet

    获取数据并设置数据为空时的默认值,如果数据不为空就能获取到该数据,如果为空则根据你传入的参数来创建对象作为默认值返回

    1
    2
    Optional<Author> authorOptional = Optional.ofNullable(getAuthor());
    Author author1 = authorOptional.orElseGet(()->new Author());

  2. orElseThrow

    获取数据,如果数据不为空就能获取该数据。如果为空则根据你传入的参数来创建异常抛出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try {
    author = optionalAuthor.orElseThrow(new Supplier<Throwable>() {
    @Override
    public Throwable get() {
    return new RuntimeException("???");
    }
    });
    } catch (Throwable e) {
    e.printStackTrace();
    }

# 过滤数据 filter

1
2
Author author1 = getAuthor().filter(author -> author.getAge()>10).orElseGet(() -> new Author(0L, "没没没名字", 0, "???", null));

# 判断 isPresent ()

判断 Optional 的值是否为空,如果不为空返回 true,为空返回 false

更推荐 ifPresent () 方法

# 数据转换

Optional 提供 map 可以进行数据转换

1
2
3
Optional<Author> author = getAuthor();
Optional<List<Book>> books = author.map(author1 -> author1.getBooks());
books.ifPresent(books1 -> books1.forEach(System.out::println));

更新于 阅读次数 本文阅读量:

请我喝[茶]~( ̄▽ ̄)~*

Windlinxy 微信支付

微信支付

Windlinxy 支付宝

支付宝