26-Optional类

(1)今天做了什么:
今天看了Optional类。Optional是用来包装可能为null的值的容器,通过显式处理空值来避免空指针异常。创建方式有三种:of()传入非空值,如果为null会立即抛异常;ofNullable()接受可能为null的值;empty()创建空的Optional。C++17也有std::optional,概念上类似,但Java的Optional更强调作为返回值类型,不推荐作为字段或方法参数使用,这点和C++不太一样。

常用方法也看了一下。isPresent()判断是否有值,get()获取值但为空时会抛异常,所以get一般配合isPresent用。orElse()提供默认值,为空时返回默认值。orElseGet()接收Supplier,为空时惰性获取默认值,如果默认值创建成本高,用orElseGet更合适。orElseThrow()为空时抛出指定异常。ifPresent()接收Consumer,有值时执行操作,没有就不做。

map和flatMap在Optional里也有,和Stream里的map/flatMap类似。map把Optional里的值转换后包装成新的Optional,flatMap用于避免嵌套Optional。filter方法过滤不符合条件的值,为空时变成空Optional。这些方法配合起来可以链式处理,避免写多层if判断空值。

(2)明天准备做什么:
明天准备看日期时间API。Java 8引入了新的日期时间API,之前用Date和Calendar有些设计问题,听说新的API更合理,想具体看看LocalDate、LocalTime、LocalDateTime、Instant这几个类的用法。

(3)遇到的问题,如何解决:
今天遇到的主要问题是orElse和orElseGet的区别。刚开始以为一样,后来发现orElse无论Optional是否为空都会执行参数里的表达式,即使最终用不上。比如orElse(getDefaultValue()),即使Optional有值,getDefaultValue也会被调用,如果这个调用开销大或者有副作用就不好。orElseGet只有在Optional为空时才执行Supplier获取默认值。和C++的std::optional的value_or类似,但C++没有orElseGet这种惰性求值的写法。另外用Optional.of(null)直接报错,应该用ofNullable,这个错误写了一次就记住了。