最近,很多读者出去面试都在Java8上栽了跟头,事后自己分析,确实对Java8的新特性一知半解。然而,却在简历显眼的技能部分写着:熟练掌握Java8的各种新特性,能够迅速使用Java8开发高并发应用!这不,又一名读者因为写了熟练掌握Java8的新特性而被面试官虐的体无完肤!我不是说不能写,可以这样写!但是,咱在写熟练掌握Java8新特性的时候,应该静下心来好好想想自己是否真的掌握了Java8。如果自己心中对是否掌握了Java8这个问题模棱两可的话,那确实要好好静下心来为自己充电了!一定要从模棱两可到彻底掌握Java8,那到时就不是面试官虐你了,而是你吊打面试官!!
什么是Optional类?Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
Optional类常用方法:
Optional.of(T t) : 创建一个 Optional 实例。
Optional.empty() : 创建一个空的 Optional 实例。
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例。
isPresent() : 判断是否包含值。
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t。
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值。
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()。
flatMap(Function mapper):与 map 类似,要求返回值必须是Optional。
Optional类示例 1.创建Optional类(1)使用empty()方法创建一个空的Optional对象:
Optional<String> empty = Optional.empty();(2)使用of()方法创建Optional对象:
String name = "binghe"; Optional<String> opt = Optional.of(name); assertEquals("Optional[binghe]", opt.toString());传递给of()的值不可以为空,否则会抛出空指针异常。例如,下面的程序会抛出空指针异常。
String name = null; Optional<String> opt = Optional.of(name);如果我们需要传递一些空值,那我们可以使用下面的示例所示。
String name = null; Optional<String> opt = Optional.ofNullable(name);使用ofNullable()方法,则当传递进去一个空值时,不会抛出异常,而只是返回一个空的Optional对象,如同我们用Optional.empty()方法一样。
2.isPresent我们可以使用这个isPresent()方法检查一个Optional对象中是否有值,只有值非空才返回true。
Optional<String> opt = Optional.of("binghe"); assertTrue(opt.isPresent()); opt = Optional.ofNullable(null); assertFalse(opt.isPresent());在Java8之前,我们一般使用如下方式来检查空值。
if(name != null){ System.out.println(name.length); }在Java8中,我们就可以使用如下方式来检查空值了。
Optional<String> opt = Optional.of("binghe"); opt.ifPresent(name -> System.out.println(name.length())); 3.orElse和orElseGet(1)orElse
orElse()方法用来返回Optional对象中的默认值,它被传入一个“默认参数‘。如果对象中存在一个值,则返回它,否则返回传入的“默认参数”。
String nullName = null; String name = Optional.ofNullable(nullName).orElse("binghe"); assertEquals("binghe", name);(2)orElseGet
与orElse()方法类似,但是这个函数不接收一个“默认参数”,而是一个函数接口。
String nullName = null; String name = Optional.ofNullable(nullName).orElseGet(() -> "binghe"); assertEquals("binghe", name);(3)二者有什么区别?
要想理解二者的区别,首先让我们创建一个无参且返回定值的方法。
public String getDefaultName() { System.out.println("Getting Default Name"); return "binghe"; }接下来,进行两个测试看看两个方法到底有什么区别。
String text; System.out.println("Using orElseGet:"); String defaultText = Optional.ofNullable(text).orElseGet(this::getDefaultName); assertEquals("binghe", defaultText); System.out.println("Using orElse:"); defaultText = Optional.ofNullable(text).orElse(getDefaultName()); assertEquals("binghe", defaultText);在这里示例中,我们的Optional对象中包含的都是一个空值,让我们看看程序执行结果:
Using orElseGet: Getting default name... Using orElse: Getting default name...两个Optional对象中都不存在value,因此执行结果相同。
那么,当Optional对象中存在数据会发生什么呢?我们一起来验证下。
String name = "binghe001"; System.out.println("Using orElseGet:"); String defaultName = Optional.ofNullable(name).orElseGet(this::getDefaultName); assertEquals("binghe001", defaultName); System.out.println("Using orElse:"); defaultName = Optional.ofNullable(name).orElse(getDefaultName()); assertEquals("binghe001", defaultName);运行结果如下所示。
Using orElseGet: Using orElse: Getting default name...