# Optional

# 概述

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

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

# 使用

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

# 传统使用

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

# Optional

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

// 源码
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
Optional<Author> optionalAuthor = Optional.ofNullable(author)
        optionalAuthor.ifPresent(author1 -> System.out.println(author1.getName()));

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

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

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

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

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

    try {
                author = optionalAuthor.orElseThrow(new Supplier<Throwable>() {
                    @Override
                    public Throwable get() {
                        return new RuntimeException("???");
                    }
                });
            } catch (Throwable e) {
                e.printStackTrace();
            }

# 过滤数据 filter

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

# 判断 isPresent ()

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

更推荐 ifPresent () 方法

# 数据转换

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

Optional<Author> author = getAuthor();
    Optional<List<Book>> books = author.map(author1 -> author1.getBooks());
    books.ifPresent(books1 -> books1.forEach(System.out::println));
更新于 阅读次数 本文阅读量:

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

Windlinxy 微信支付

微信支付

Windlinxy 支付宝

支付宝