java8函数式编程学习(四)- Optional

2022/3/30 11:49:51

本文主要是介绍java8函数式编程学习(四)- Optional,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

4. Optional

4.1 概述

我们在编写代码的时候出现最对的就是空指针异常。所以我们需要在各种情况下做非空判断。

List<Author> authors = StreamDemo.getAuthors();
if (CollectionUtils.isNotEmpty(authors)) {
    Author author = authors.get(0);
    if (null != author) {
        System.out.println(author.getName());
    }
}

尤其对象中的属性还是一个对象时,这种判断会更多。而过多的判断语句让我们的代码显得臃肿不堪。
所以JDK8引入了Optional,养成了使用Optional的习惯后你可以写出更优雅的代码来避免空指针异常。
并且在很多函数式编程相关的API也用到了Optional。

4.2 使用

基础方法

public static Author getAuthor() {
    Author author = new Author(1L, "蒙多", 33, "测试人1", null);
    return author;
}

public static Optional<Author> getAuthorOptional() {
    Author author = new Author(1L, "蒙多", 33, "测试人1", null);
    return Optional.ofNullable(author);
}

4.2.1 创建对象

Optional就好像是包装类,可以把我们的具体数据封装到Optional对象内部。然后我们去使用Optional中封装好的方法操作数据就可以非常优雅的避免空指针。

// 例子:我们一般使用Optional的静态方法ofNullable来把数据封装成Optional对象,传入的参数是否为null都不会出现问题
Author author = getAuthor();
Optional<Author> authorOptional = Optional.ofNullable(author);
authorOptional.ifPresent(authorBean -> System.out.println(authorBean));

// 一般情况都是返回Optional对象的  优化后
Optional<Author> authorOptional1 = getAuthorOptional();
authorOptional1.ifPresent(authorBean -> System.out.println(authorBean));

// 在实际开发中我们的数据大都是从数据库中获取的,Mybatis从3.5版本开始已经可以支持Optional了。
// 我们可以直接把dao方法的返回值类型定义成Optional类型,Mybatis会自己把数据封装成Optional对象返回,封装过程不需要我们自己来操作。

// 如果你确定一个对象不是空的则可使用Optional的静态方法of来把数据封装成Optional对象。
Author author1 = new Author();
Optional<Author> author1Optional = Optional.of(author1);
// 一定要注意,使用of的时候传入的参数必须不为null(会出现空指针异常)。

// 如果一个方法的返回值类型是Optional类型,而如果判断发现返回值为null,则需要把null封装成Optional对象返回,调用Optional的静态方法empty()。
Optional.empty();

4.2.2 安全消费值

我们获取到一个Optional对象后肯定需要对其中的数据进行使用,这时候我们可以用ifPresent方法来消费其中的值。
这个方法会判断其内封装的数据是否为空,不为空时才会执行具体的消费代码,这样使用起来就更加安全。

// 例子
Author author = getAuthor();
Optional<Author> authorOptional = Optional.ofNullable(author);
authorOptional.ifPresent(authorBean -> System.out.println(authorBean));

4.2.3 获取值

如果我们想获取值自行处理可以使用get方法获取,但是不推荐。因为Optional内部的数据为空是会出现异常。

// 例子
Optional<Author> authorOptional = getAuthorOptional();
Author author1 = authorOptional.get();

4.2.4 安全获取值

如果我们想安全获取值,不推荐使用get方法,而是使用Optional提供的一下方法。

// orElseGet
// 获取数据并设置如果数据为空时的默认值,如果数据不为空就可以获取到,如果数据为空时则根据你传入的参数来创建对象作为默认值返回。
Optional<Author> authorOptional = getAuthorOptional();
Author author = authorOptional.orElseGet(() -> new Author());

// orElseThrow
// 获取数据,如果数据不为空就能获取到该数据,如果为空则根据你传入的参数来创建异常抛出
try {
    authorOptional.orElseThrow((Supplier<Throwable>) () -> new RuntimeException("author为空。"));
} catch (Throwable throwable) {
    throwable.printStackTrace();
}

4.2.5 过滤

我们可以使用filter方法对数据进行过滤,如果原本是有数据的,但是不符合判断,也会变成一个无数据的Optional对象。

Optional<Author> authorOptional = getAuthorOptional();
authorOptional.filter(author -> author.getAge() > 100)
    .ifPresent(author -> System.out.println(author.getName()));

4.2.6 判断

我们可以使用isPresent方法进行是否存在数据的判断。如果为空返回值为false。不为空返回true。
更推荐使用ifPresent方法

Optional<Author> authorOptional = getAuthorOptional();
authorOptional.filter(author -> author.getAge() > 100)
    .ifPresent(author -> System.out.println(author.getName()));

4.2.7 数据转换

optional还提供了map可以让我们对数据进行转换,并且转换得到的数据还是被Optional包装好的,保证了我们的使用安全。
更推荐使用ifPresent方法

// 例如:获取作家的书籍集合
Optional<Author> authorOptional = getAuthorOptional();
Optional<List<Book>> optionalBooks = authorOptional.map(author -> author.getBooks());
optionalBooks.ifPresent(books -> books.forEach(book -> System.out.println(book)));


这篇关于java8函数式编程学习(四)- Optional的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程