Java8_Optional
Optional:
1.问题引入
空指针问题是我们在开发中经常遇到的问题,例如:
class People{
public String name ;
private int age;
public int getAge(){
return age;
}
public static void main(String args[])
{
People people;
int age = people.getAge();
}
//会抛出空指针异常
}
传统的改正方法:
public static void main(String args[]){
Peple people ;
if( people == null)
people = new People();
int age = people.getAge();
}
对于空指针问题,传统的方法是通过if 显式的判断对象是否为空或者使用try(){}catch{}语句,但是这样需要大量的显式操作,每遇到一个对象,都需要一个判断语句;因此,Java8引入Optional对象来避免空指针问题。
2.解决方法:Optional类
Optional类会对类进行简单的封装,变量不存在时,缺失的值会被建模成一个空的optional对象,由方法Optional.empty()返回,如果变量存在的话,返回包含的类型。
空的Optional对象和null之间的区别:
如果想解引用一个null,会触发空指针异常,使用Optioinal.empty()方法不会。
创建Optional对象:
Optional<People> optpeo = Optional.empty();
Optional<People> optpeo = Optional.of(people);
Optioinal<People> optpeo = Optional.ofNullable(people);// 允许null值的Optional对象;
Optional的Map方法和flatMap方法:
Optinal类提供一个map方法,用来提取和转换optional对象中的值,Optional<Integer> age = optpeo.map(people::getage);map方法会将函数应用到流中的每个元素;flatMap方法用来链接Optional对象:
Optional<people> optPeople = Optional.of(people);
Optional<Double> prices =
optPerson.map(people::getCar)
.map(Car::getType)
.map(Type::getPrice);
/**
* people::getCar 返回一个optional<Car> ,optPerson.map(function) ,因此 整体返回一个 Optional<Optional<Car>>,
因此调用getType()方法出错,因为getType()方法属于Car类,只有Optional<Car>可以调用
*
*/
class People{
Optional<Car> car;
public Optional<Car> getCar(){
return car;
}
}
class Car{
Optional<Type> type;
public Optional<Type> getType(){
return type;
}
}
class Type{
double price ;
public double getPrice(){
return price;
}
}
上述代码在运行的过程中会报错;
map方法的函数签名为:public <U> Optional<U> map(Function<? super T, ? extends U> mapper)
解决方式是:使用flatMap方法,flatMap方法接受一个函数作为参数,这个函数的返回值是另一个流,即flatMap会用流的内容替换每个新生成的流。就上面的例子分析,因为map也会将函数应用于流中的每个元素,但是它的流中的元素进行了包装,下次继续使用此流使调用map方法的时候,流中的元素已经不具备某些条件,因此我们需要的在经过了函数的调用后,返回的流的内容组成的新流;
因此,上面的代码可以改写为:
public double getCarPrice(Optional<People> people)
{
return people.flatMap(People::getCar)
.flatMap(Car::getType)
.map(Type::getPrice)
.orElse(“Unknow”);
}
Optional的默认行为:
Optional类提供了多种方法读取Optional实例中的变量值:
get():如果变量存在,它直接返回封装的变量值,否则抛出异常;
orElse(T other):当对象不存在的时候,返回一个默认值;
orElseGet(Supplier<? extends T> supplier) 只有当Optional中不含值的时候才会被调用,
orElseThrow:当Optoinal对象为空的时候抛出一个异常,只不过这个异常可以进行定制;
ifPresent(): 判断值是否为空;
filter:筛选
Optional<T> filter(Predicate<? super T> predicate):使用filter可以进行Optional对象的筛选,他接受一个predicate接口的对象,返回一个boolean值,如果值为true,就将元素添加到Optional中。
内容参考《Java8 实战》 ,,由衷感谢此书作者为我们提供学习内容