Java8 引入的 Optional类。主要用来解决空指针异常(NullPointerException),空指针异常是导致Java应用程序失败的最常见原因。
Optional类可以理解为一个容器:它既可以保存类型T的对象,也可以保存null。
Optional类提供了很多有用的方法,并实现了检查空值的功能,程序员就不用显式地写空值检测的代码,再结合函数式编程,使得代码更加干净,简洁。
一、Optional类的使用 1、创建 Optional实例1.1 of方法Optional类可以理解为一个容器:它既可以保存类型 T的对象,也可以保存 null。
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); Optional1.2 ofNullable方法optionalJUser = Optional.of(jUser); System.out.println(optionalJUser.get()); // 输出结果:jUser信息 jUser = null; Optional optionalJUser2 = Optional.of(jUser); System.out.println(optionalJUser2.get()); // 输出结果:java.lang.NullPointerException }
ofNullable:为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
@Test public void testOfNullable(){ JUser jUser = null; Optional1.3 empty方法optionalJUser = Optional.ofNullable(jUser); System.out.println(optionalJUser); // 输出结果:Optional.empty JUser jUser1 = optionalJUser.get();// 输出结果:在这一行报错啦,java.lang.NullPointerException: No value present }
empty:返回一个空 Optional实例。
注意: Optional.empty() 所有保存 null包装成的 Optional对象,而且是单例模式的。与泛型无关。
@Test public void testEmpty(){ Optional2、验证 Optional实例 2.1 isPrensent方法
isPrensent:如果值存在返回true,不存在返回false。
@Test public void testIsPresent(){ JUser jUser = null; Optional2.2 ifPresent方法optionalJUser = Optional.ofNullable(jUser); boolean present = optionalJUser.isPresent(); System.out.println(present); // 输出结果:false }
ifPresent:接受一个Consumer参数,如果对象不为空,就调用consumer接口。否则不做处理。
@Test public void testIfPresent(){ JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); jUser.setPazzword("abc123"); jUser.setHeight(1.78D); Optional3、Optional实例使用 3.1 get方法optionalJUser = Optional.ofNullable(jUser); optionalJUser.ifPresent(u -> { // 不为 null时才会执行断言 System.out.println(u);// 输出结果:jUser信息 }); }
get:如果有值则返回,没有值抛出 NoSuchElementException异常
@Test public void testGet(){ JUser jUser = null; Optional3.2 orElse(方法optionalJUser = Optional.ofNullable(jUser); // JUser jUser1 = optionalJUser.get(); // 输出结果:java.lang.NullPointerException // 可以使用 isPresent方法检查 if(optionalJUser.isPresent()){ System.out.println(optionalJUser.get());// 输出结果:此时为空,不执行该语句 } }
orElse(T other):如果保存的值不是null,则返回原来的值,否则返回 other。
@Test public void testOrElse(){ JUser jUser = null; Optional3.3 orElseGet方法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} }
orElseGet(Supplier extends T> other):
如果保存的值不是null,则返回原来的值,否则调用 生产者函数 并返回调用结果的。
@Test public void testOrElseGet(){ JUser jUser = null; OptionaloptionalJUser = 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值时,两者调用方法的效果一样的。
orElseThrow(Supplier extends X> exceptionSupplier):有值返回,没有值抛出 supplier接口创建的异常
@Test public void testOrElseThrow(){ JUser jUser = null; Optional3.5 map方法optionalJUser = Optional.ofNullable(jUser); JUser jUser1 = optionalJUser.orElseThrow(() -> { return new RuntimeException("testOrElseThrow "); }); // 输出结果:java.lang.RuntimeException: testOrElseThrow }
map(Function super T,? extends U> mapper):
有值,就调用 Function函数并返回生成的值。否则返回空的Optional。
@Test public void testMap(){ JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional3.6 flatMap方法optionalJUser = Optional.ofNullable(jUser); Optional 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 }
flatMap(Function super T, ? extends Optional extends U>> mapper):
它map类似,区别在于他调用结束的时候,不会对Optional做一个封装
@Test public void testFlatMap() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional3.7 filter方法optionalJUser = Optional.ofNullable(jUser); Optional 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 }
filter:有值,返回满足条件的Optional。否则返回空的Optional
@Test public void testFilter() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); Optional4、Optional类的链式方法 二、JDK9的增强optionalJUser = Optional.ofNullable(jUser); // 没有满足的,返回空的Optional Optional optionalJUser1 = optionalJUser.filter(u -> { return u.getId() == 1; }); System.out.println(optionalJUser1.get());// 输出结果:java.util.NoSuchElementException: No value present }
上面介绍了 Java 8 的特性,Java 9 为 Optional 类添加了三个方法:
- or()
- ifPresentOrElse()
- stream()。
or() 方法与 orElse() 和 orElseGet() 类似,它们都在对象为空的时候提供了替代情况。
or() 的返回值是由 Supplier 参数产生的另一个 Optional 对象。
@Test public void testOr() { JUser jUser = null; Optional2、ifPresentOrElse方法optionalJUser = Optional.ofNullable(jUser); Optional optionalJUser1 = optionalJUser.or(() -> { JUser u = new JUser(); u.setId(100L); u.setUsername("赵云"); return Optional.of(u); }); System.out.println(optionalJUser1.get());// 输出结果:u信息 }
ifPresentOrElse(Consumer super T> action, Runnable emptyAction):
如果对象包含值,会执行 Consumer 的动作,否则运行 Runnable。
@Test public void testIfPresentOrElse() { JUser jUser = null; Optional3、stream方法optionalJUser = Optional.ofNullable(jUser); optionalJUser.ifPresentOrElse(u -> System.out.printf("user id = {}" + u.getId()), () -> System.out.printf("User not found")); // 输出结果:User not found }
stream() 方法,它通过把实例转换为 Stream对象,让你从广大的 Stream API中受益。如果没有值,它会得到空的 Stream;有值的情况下,Stream则会包含单一值。
@Test public void testStream() { JUser jUser = new JUser(); jUser.setId(100L); jUser.setUsername("赵云"); ListjUserList = 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
– 求知若饥,虚心若愚。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)