空指针问题是我们在开发中经常遇到的问题,例如:
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对象来避免空指针问题。
Optional类会对类进行简单的封装,变量不存在时,缺失的值会被建模成一个空的optional对象,由方法Optional.empty()返回,如果变量存在的话,返回包含的类型。
空的Optional对象和null之间的区别:
如果想解引用一个null,会触发空指针异常,使用Optioinal.empty()方法不会。
Optional optpeo = Optional.empty();
Optional optpeo = Optional.of(people);
Optioinal optpeo = Optional.ofNullable(people);// 允许null值的Optional对象;
Optinal类提供一个map方法,用来提取和转换optional对象中的值,Optional
Optional optPeople = Optional.of(people);
Optional prices =
optPerson.map(people::getCar)
.map(Car::getType)
.map(Type::getPrice);
/**
* people::getCar 返回一个optional ,optPerson.map(function) ,因此 整体返回一个 Optional>,
因此调用getType()方法出错,因为getType()方法属于Car类,只有Optional可以调用
*
*/
class People{
Optional car;
public Optional getCar(){
return car;
}
}
class Car{
Optional type;
public Optional getType(){
return type;
}
}
class Type{
double price ;
public double getPrice(){
return price;
}
}
上述代码在运行的过程中会报错;
map方法的函数签名为:public Optional map(Function super T, ? extends U> mapper)
解决方式是:使用flatMap方法,flatMap方法接受一个函数作为参数,这个函数的返回值是另一个流,即flatMap会用流的内容替换每个新生成的流。就上面的例子分析,因为map也会将函数应用于流中的每个元素,但是它的流中的元素进行了包装,下次继续使用此流使调用map方法的时候,流中的元素已经不具备某些条件,因此我们需要的在经过了函数的调用后,返回的流的内容组成的新流;
因此,上面的代码可以改写为:
public double getCarPrice(Optional 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
内容参考《Java8 实战》 ,,由衷感谢此书作者为我们提供学习内容