前言
Java8引入了一些新的特性,比如lambda表达式、Stream流,当然了,还有这篇要说的Optional,它主要就是解决NullPointerException,用法其实也没多少,他的接口也就十来个,来个图一下展示出来:
接下来,我们就围绕这些API来了解Optional。
使用
of与ofNullable
这俩是比较类似的,无论是of还是ofNullable,他们都会返回of()/ofNullable()括号中的内容,区别在于of()里面如果为空的话,还是会报空指针异常的,而ofNullable是不会报空指针异常的:
Optional<Object> optionalOf = Optional.of(null);
Optional<String> of = Optional.of("of");
在运行上面两行代码的时候,遇到第一行就会出错误了,因为of中是null,所以这时就需要ofNullable了,
Optional<Object> optional = Optional.ofNullable(null);
Optional<String> ofNullable =Optional.ofNullable("ofNullable");
get
我们通过of/ofNullable是得到包含数据类型的Optional,但是这并不是我们想要的,通过get方法可以得到我们想要的数值。
Optional<String> ofNullable =Optional.ofNullable("ofNullable");
System.out.println(ofNullable.get());
orElse
可惜的是,虽然我们在使用ofNullable时,即使参数为空不会出现空指针异常,但是在get的时候还是无法避免空指针。
Optional<Object> optional = Optional.ofNullable(null);
System.out.println(optional.get());
这样的情况下还是会抛异常,似乎使用Optinal还是无法避免空指针异常,这与Optional的介绍是相背的。
事实上,Optional提供了orElse可以使得我们来避免空指针异常。
Object orElse = Optional.ofNullable(null).orElse("orElse");
他的含义是:看ofNullable中的值是否为空,如果不为空,那么就返回ofNullable中的值,否则就返回orElse中的值。
orElseGet、orElseThrow
orElseGet:可以类比于orElse,只不过orElseGet中是一个Supplier接口,可以在里面实现一些自定义逻辑:
User user=new User();
String s = Optional.ofNullable(user.getName()).orElseGet(() -> "name");
System.out.println(s);
orElseThrow:当of/ofnullable为空的时候,执行orElseThrow抛出一个自定义异常
User user=new User();
String s = Optional.ofNullable(user.getName()).orElseThrow(()->new NumberFormatException());
System.out.println(s);
可以看到执行结果确实是抛出了一个数字格式异常的错误:
Exception in thread "main" java.lang.NumberFormatException
at com.dong.OptionalTest.lambda$main$0(OptionalTest.java:24)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.dong.OptionalTest.main(OptionalTest.java:24)
map
map方法中是一个Function函数,通过这个Function函数,我们可以得到想要的结果,比如想要获取一个实体类的某个属性:
System.out.println("map------");
User user=new User();
user.setAge(18);
user.setName("tom");
System.out.println(Optional.ofNullable(user).map(User::getAge).get());
运行结果:
map------
18
flatMap
flatMap与map其实也类似,但是两者也是存在一定的区别的,主要是在于返回值,map对返回值回使用Optional进行包装。
Optional<Object> empty = Optional.of("123");
Optional<Object> optional = Optional.ofNullable(null).map(p -> Optional.ofNullable(p)).orElse(empty);
Object orElse = empty.flatMap(p -> Optional.ofNullable(p)).orElse("orElse");
filter(过滤)
如果用过Stream流的话,这个就会很熟悉了。其实Optional中的filter与stream中的filter是差不多的,都是通过输入的条件进行过滤,然后筛选出符合条件的数据。
System.out.println("filter-----");
User user=new User();
user.setAge(18);
user.setName("tom");
System.out.println(Optional.ofNullable(user).filter(p -> p.getAge() == 18).map(User::getName).get());
运行结果:
filter-----
tom
isPresent
isPresent方法的返回值为boolean类型,他是判断Optional类型的变量中是否有值。
System.out.println(Optional.empty().isPresent());
System.out.println(Optional.ofNullable("ofNullable").isPresent());
ifPresent
在上面的isPresent,会根据是否有值来判定返回false还是true,这个ifPresent会根据是否有值来执行ifPresent中的Consumer方法。
Optional.empty().ifPresent(p-> System.out.println("123"));
Optional.ofNullable("ofNullable").ifPresent(p-> System.out.println("of"));
以上就是Optional的一些简单用法,他的用法其实还是比较简单的,而且接口也比较少,学习使用起来也是比较快的。