Optional

一、概述

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

例如:

 

scss

代码解读

复制代码

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

尤其是对象中的属性还是一个对象的情况下。这种判断会更多。

而过多的判断语句会让我们的代码显得臃肿不堪。

所以在JDK8中引入了Optional,养成使用Optional的习惯后你可以写出更优雅的代码来避免空指针异常。

并且在很多函数式编程相关的API中也都用到了Optional,如果不会使用Optional也会对函数式编程的学习造成影响。

二、使用

2.1 创建对象

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

我们一般使用Optional的静态方法ofNullable来把数据封装成一个Optional对象。无论传入的参数是否为null都不会出现问题

 

ini

代码解读

复制代码

Author author = getAuthor(); Optional<Author> authorOptional = Optional.ofNullable(author);

你可能会觉得还要加一行代码来封装数据比较麻烦。但是如果改造下getAuthor方法,让其的返回值就是封装好的Optional的话,我们在使用时就会方便很多。

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

2.2 安全消费值

我们获取到一个Optional对象后肯定需要对其中的数据进行使用。这时候我们可以使用其ifPresent方法对来消费其中的值。

这个方法会判断其内封装的数据是否为空,不为空时才会执行具体的消费代码。这样使用起来就更加安全了。

例如,以下写法就优雅的避免了空指针异常。

 

ini

代码解读

复制代码

Optional<Author> authorOptional = Optional.ofNullable(getAuthor()); authorOptional.ifPresent(author ->System.out.println(author.getName()));

底层参数为Consumer接口,外部调用后要使用匿名内部类,重写方法,所以可以使用lambda

2.3 获取值

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

 

ini

代码解读

复制代码

List<Author> authors = getAuthors(); Author author = authors.get(0); Optional<Author> optional = Optional.ofNullable(author); Author author2 = optional.get(); System.out.println(author2);

2.4 安全获取值

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

  • orElseGet

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

 

vbnet

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); optional.orElseGet(new Supplier<Author>() { @Override public Author get() { return new Author(); } });

简化:

 

vbnet

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); optional.orElseGet(() -> new Author());

  • orElseThrow

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

 

php

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(null); try { Author author1 = optional.orElseThrow(new Supplier<Throwable>() { @Override public Throwable get() { return new RuntimeException("哈哈哈哈"); } }); System.out.println(author1); } catch (Throwable e) { throw new RuntimeException(e); }

简化:

 

php

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(null); try { Author author1 = optional.orElseThrow(() -> new RuntimeException("哈哈哈")); System.out.println(author1); } catch (Throwable e) { throw new RuntimeException(e); }

2.5 过滤

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

 

ini

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); optional.filter(author1 -> author1.getAge() > 1000).ifPresent(author1 -> System.out.println(author1));

不符合过滤条件,结果为空

 

ini

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); optional.filter(author1 -> author1.getAge() > 10).ifPresent(author1 -> System.out.println(author1));

符合过滤条件,有结果

2.6 判断

我们可以使用isPresent方法进行是否存在数据的判断。如果为空返回值为false,如果不为空,返回值为true。但是这种方式并不能体现Optional的好处,更推荐使用ifPresent方法。

 

ini

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); if(optional.isPresent()) { System.out.println(111); }

2.7 数据转换

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

例如:我们想获取作家的书籍集合。

 

ini

代码解读

复制代码

Optional<Author> optional = Optional.ofNullable(author); Optional<List<Book>> books = optional.map(author1 -> author1.getBooks()); books.ifPresent(books1 -> System.out.println(books1));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值