JDK8的Optional特性

一、Optional的介绍

在实际开发中,最让人头疼的就是NullPointerException,为了解决这个问题,我们常常需要使用if语句进行判断,进行防御性的检查,非常繁琐,对于组合了很多甚至多层组合的对象,每一层的拆解都需要判断,这是很可怕的。

在JDK1.8中,引入了Optional类,可以帮助我们省掉繁琐的非空判断。

二、Optional的常用方法

方法描述
of把指定的值封装为Optional对象,如果指定的值为null,则抛出NullPointerException
empty创建一个空的Optional对象
ofNullable把指定的值封装为Optional对象,如果指定的值为null,则创建一个空的Optional对象
get如果创建的Optional中有值存在,则返回此值,否则抛出NoSuchElementException
orElse如果创建的Optional中有值存在,则返回此值,否则返回一个默认值
orElseGet如果创建的Optional中有值存在,则返回此值,否则返回一个由Supplier接口生成的值
orElseThrow如果创建的Optional中有值存在,则返回此值,否则抛出一个由指定的Supplier接口生成的异常
filter如果创建的Optional中的值满足filter中的条件,则返回包含该值的Optional对象,否则返回一个空的Optional对象
map如果创建的Optional中的值存在,对该值执行提供的Function函数调用
flagMap如果创建的Optional中的值存在,就对该值执行提供的Function函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象
isPresent如果创建的Optional中的值存在,返回true,否则返回false
ifPresent如果创建的Optional中的值存在,则执行该方法的调用,否则什么也不做

三、Optional方法示范

3.1 empty\of\ofNullable

这三个方法是创建Optional类的起始方法,其他都是Optional方法的调用。

@Test
public void testOptional() {
    Goods goods = null;
    Optional.of(goods); //抛出异常
    Optional.ofNullable(goods); //不跑出异常
}

如果即使为空也希望通过Optional进行后续操作,比如orElse,建议使用ofNullable创建

3.2 get

这个方法会检查Optional中是否有值存在,而不是检查Optional是否为null,.ofNullable方法会创建一个空的Optional对象,而不是一个我们传入的对象,所以如果我们传入的对象是空的,get方法同样报异常

3.3 Map和orElse的联合妙用

这两个方法的妙用就可以解决我们所谓的多层组合对象层层判空的问题。

我们模拟一个场景:学校类School,里面包含有一个教师组类TeacherGroup,教师组类里包含的是我们想得到的教师集合TeacherList

List<Teacher> teachers = Lists.newArrayList(
        new Teacher("法外狂徒张三"),
        new Teacher("耗子尾汁")
);
TeacherGroup teacherGroup = new TeacherGroup(teachers);
School school = new School(teacherGroup);

我们就可以使用Map和orElse进行多重处理,保证代码的简洁

List<Teacher> teachersList = Optional.ofNullable(school) //判断学校类是否为空,同时创建Optional类进行后续操作
        .map(School::getTeacherGroup) //判断教师组是否为空
        .map(TeacherGroup::getTeachers) //判断教师集合是否为空
        .orElse(Lists.newArrayList()); //以上有一个不满足,新建集合,否则返回获取到的教师集合

//打印
[{"name":"法外狂徒张三"},{"name":"耗子尾汁"}]

//置空
School school = null; //打印结果为 []
TeacherGroup teacherGroup = null; //打印结果为[]
List<Teacher> teachers = null; //打印结果为[]

3.4 isPresent 和 ifPresent

isPresent是判定,传入的对象是否为空

Teacher teacher = null;
System.out.println(Optional.ofNullable(teacher).isPresent()); //false

Teacher teacher = new Teacher(); //true

ifPresent里面是Consumer函数式接口,也就是说,如果对象为空,不做操作,否则对对象进行操作处理。

Teacher teacher = new Teacher();
Optional.ofNullable(teacher).ifPresent(e -> e.setName("耗子尾汁"));
System.out.println(JackSonUtil.objToJson(teacher)); //打印 {"name":"耗子尾汁"}

Teacher teacher = null; //打印 null

3.5 FlatMap展开

这个类似于Stream的展开操作,这里不详细讲述,参考Stream API的使用

3.6 orElseGet和orElseThrow

orElseGet不同于orElse,这个是要调用一个兜底的方法

@Test
public void testOrElseGet() {
    List<Teacher> teachers = null;
    List<Teacher> teachers1 = Optional.ofNullable(teachers)
        
            //supplier函数式接口,需要传入某个类的方法,本类调用必须使用this::
            .orElseGet(this::getDefaultTeachers); 
    System.out.println(JackSonUtil.objToJson(teachers1));
}

orElseThrow抛出异常

@Test
public void testOrElseGet() throws Exception {
    List<Teacher> teachers = null;
    List<Teacher> teachers1 = Optional.ofNullable(teachers)
            .orElseThrow(Exception::new);
}

3.7 Filter

Filter建议和orElse/orElseGet/orElseThrow联用

@Test
public void testOptionalFilter() {
    Teacher teacher = new Teacher("法外狂徒");
    Teacher teacher1 = Optional.ofNullable(teacher)
            .filter(t -> !t.getName().equals("法外狂徒"))
            .orElse(new Teacher("耗子尾汁"));
    System.out.println(JackSonUtil.objToJson(teacher1)); //{"name":"耗子尾汁"}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值