您当前的位置: 首页 >  Java

Java8/9 Optional使用

发布时间:2021-11-10 22:24:15 ,浏览量:8

Java8 引入的 Optional类。主要用来解决空指针异常(NullPointerException),空指针异常是导致Java应用程序失败的最常见原因。

Optional类可以理解为一个容器:它既可以保存类型T的对象,也可以保存null。

Optional类提供了很多有用的方法,并实现了检查空值的功能,程序员就不用显式地写空值检测的代码,再结合函数式编程,使得代码更加干净,简洁。

一、Optional类的使用

在这里插入图片描述

1、创建 Optional实例

Optional类可以理解为一个容器:它既可以保存类型 T的对象,也可以保存 null。

1.1 of方法

of:为非null的值创建一个optional,如果传入为null,则会空指针。

@Test public void testOf(){ JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); jUser.setPazzword("abc123"); jUser.setHeight(1.78D); jUser.setBirthday(new Date()); jUser.setStatus(JUserStatusEnum.ACTIVATE); Optional<JUser> optionalJUser = Optional.of(jUser); System.out.println(optionalJUser.get()); // 输出结果:jUser信息 jUser = null; Optional<JUser> optionalJUser2 = Optional.of(jUser); System.out.println(optionalJUser2.get()); // 输出结果:java.lang.NullPointerException } 
1.2 ofNullable方法

ofNullable:为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

@Test public void testOfNullable(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); System.out.println(optionalJUser); // 输出结果:Optional.empty JUser jUser1 = optionalJUser.get();// 输出结果:在这一行报错啦,java.lang.NullPointerException: No value present } 
1.3 empty方法

empty:返回一个空 Optional实例。

注意: Optional.empty() 所有保存 null包装成的 Optional对象,而且是单例模式的。与泛型无关。

@Test public void testEmpty(){ Optional<Object> empty = Optional.empty(); System.out.println(empty); // 输出结果:Optional.empty Object o1 = Optional.<Integer>empty(); Object o2 = Optional.<String>empty(); System.out.println(o1 == o2);// 输出结果:true } 
2、验证 Optional实例 2.1 isPrensent方法

isPrensent:如果值存在返回true,不存在返回false。

@Test public void testIsPresent(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); boolean present = optionalJUser.isPresent(); System.out.println(present); // 输出结果:false } 
2.2 ifPresent方法

ifPresent:接受一个Consumer参数,如果对象不为空,就调用consumer接口。否则不做处理。

@Test public void testIfPresent(){ JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); jUser.setPazzword("abc123"); jUser.setHeight(1.78D); Optional<JUser> optionalJUser = Optional.ofNullable(jUser); optionalJUser.ifPresent(u -> { // 不为 null时才会执行断言 System.out.println(u);// 输出结果:jUser信息 }); } 
3、Optional实例使用 3.1 get方法

get:如果有值则返回,没有值抛出NoSuchElementException异常

@Test public void testGet(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); //        JUser jUser1 = optionalJUser.get(); // 输出结果:java.lang.NullPointerException // 可以使用 isPresent方法检查 if(optionalJUser.isPresent()){ System.out.println(optionalJUser.get());// 输出结果:此时为空,不执行该语句 } } 
3.2 orElse(方法

orElse(T other):如果保存的值不是null,则返回原来的值,否则返回 other。

@Test public void testOrElse(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); JUser jUser1 = optionalJUser.orElse(new JUser()); System.out.println(jUser1);// 输出结果:jUser实例的默认信息 // JUser{id=null, username='null', pazzword='null', age=null, age2=0, sex=null, height=null, height2=0.0, birthday=null, status=null} } 
3.3 orElseGet方法

orElseGet(Supplier other): 如果保存的值不是null,则返回原来的值,否则调用 生产者函数 并返回调用结果的。

@Test public void testOrElseGet(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); JUser jUser1 = optionalJUser.orElseGet(() -> { JUser u = new JUser(); u.setId(100L); u.setUsername("赵云"); return u; }); System.out.println(jUser1);// 输出结果:u实例信息 // JUser{id=100, username='赵云', pazzword='null', age=null, age2=0, sex=null, height=null, height2=0.0, birthday=null, status=null} } 

注意:orElse和 orElseGet方法的区别

  • 如果 Optional保存的是 null值时,两者调用方法的效果一样的。但是,orElse可以返回任何类型 T的值,而 orElseGet必须是 Supplier函数返回的调用结果。
  • 如果 Optional保存的不是 null值时,两者调用方法的效果一样的。
3.4 orElseThrow方法

orElseThrow(Supplier exceptionSupplier):有值返回,没有值抛出 supplier接口创建的异常

@Test public void testOrElseThrow(){ JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); JUser jUser1 = optionalJUser.orElseThrow(() -> { return new RuntimeException("testOrElseThrow "); }); // 输出结果:java.lang.RuntimeException: testOrElseThrow  } 
3.5 map方法

map(Function mapper): 有值,就调用 Function函数并返回生成的值。否则返回空的Optional。

@Test public void testMap(){ JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional<JUser> optionalJUser = Optional.ofNullable(jUser); Optional<JUser> optionalJUser1 = optionalJUser.map((u) -> { u.setId(u.getId() + 100L); u.setUsername("赵云2"); return u; }); System.out.println(optionalJUser1.get());// 输出结果:JUser{id=200, username='赵云2', pazzword='null', age=null, age2=0, sex=null, height=null, height2=0.0, birthday=null, status=null} // 如果 jUser= null,则输出结果:java.lang.NullPointerException } 
3.6 flatMap方法

flatMap(Function> mapper): 它map类似,区别在于他调用结束的时候,不会对Optional做一个封装

@Test public void testFlatMap() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional<JUser> optionalJUser = Optional.ofNullable(jUser); Optional<JUser> optionalJUser1 = optionalJUser.flatMap((u) -> { //需要我们自己的去封装一个Optional u.setId(u.getId() + 100L); u.setUsername("赵云2"); return Optional.of(u); }); System.out.println(optionalJUser1.get());// 输出结果:JUser{id=200, username='赵云2', pazzword='null', age=null, age2=0, sex=null, height=null, height2=0.0, birthday=null, status=null} // 如果 jUser= null,则输出结果:java.lang.NullPointerException } 
3.7 filter方法

filter:有值,返回满足条件的Optional。否则返回空的Optional

@Test public void testFilter() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional<JUser> optionalJUser = Optional.ofNullable(jUser); // 没有满足的,返回空的Optional Optional<JUser> optionalJUser1 = optionalJUser.filter(u -> { return u.getId() == 1; }); System.out.println(optionalJUser1.get());// 输出结果:java.util.NoSuchElementException: No value present } 
4、Optional类的链式方法

在这里插入图片描述

二、JDK9的增强

上面介绍了 Java 8 的特性,Java 9 为 Optional 类添加了三个方法:

  • or()
  • ifPresentOrElse()
  • stream()。
1、or方法

or() 方法与 orElse() 和 orElseGet() 类似,它们都在对象为空的时候提供了替代情况。

or() 的返回值是由 Supplier 参数产生的另一个 Optional 对象。

@Test public void testOr() { JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); Optional<JUser> optionalJUser1 = optionalJUser.or(() -> { JUser u = new JUser(); u.setId(100L); u.setUsername("赵云"); return Optional.of(u); }); System.out.println(optionalJUser1.get());// 输出结果:u信息 } 
2、ifPresentOrElse方法

ifPresentOrElse(Consumer action, Runnable emptyAction): 如果对象包含值,会执行 Consumer 的动作,否则运行 Runnable。

@Test public void testIfPresentOrElse() { JUser jUser = null; Optional<JUser> optionalJUser = Optional.ofNullable(jUser); optionalJUser.ifPresentOrElse(u -> System.out.printf("user id = {}" + u.getId()), () -> System.out.printf("User not found")); // 输出结果:User not found } 
3、stream方法

stream() 方法,它通过把实例转换为 Stream对象,让你从广大的 Stream API中受益。如果没有值,它会得到空的 Stream;有值的情况下,Stream则会包含单一值。

@Test public void testStream() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); List<JUser> jUserList = Optional.ofNullable(jUser) .stream() .filter(u -> u.getId() == 100) .map(u -> { u.setId(u.getId() + 100L); u.setUsername("赵云2"); return u; }) .collect(Collectors.toList()); System.out.println(jUserList);// 输出结果:数据 } 

在这里插入图片描述

总结: Optional 是 Java 语言的有益补充 —— 它旨在减少代码中的 NullPointerExceptions,虽然还不能完全消除这些异常。它也是精心设计,自然融入 Java 8 函数式支持的功能。 总的来说,这个简单而强大的类有助于创建简单、可读性更强、比对应程序错误更少的程序。

参考文章:

  • 理解、学习与使用 Java 中的 Optional:https://www.cnblogs.com/zhangboyu/p/7580262.html

– 求知若饥,虚心若愚。

关注
打赏
1688896170
查看更多评论

暂无认证

  • 8浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0377s