Optional常见方法以及实战落地

发布于:2022-12-10 ⋅ 阅读:(301) ⋅ 点赞:(0)

背景

大家都知道jdk1.8新增了一个Optional类,它是为了解决项目中出现的NullPointerException(空指针异常),今天我们一起来学习下它的用法和实战落地吧。

常见方法

of(T value):

    /**
     * of(T value): 把指定的对象封装为Optional对象,如果它为null,则抛出NullPointerException
     */
    @Test
    public void test1() {
        // 创建一个值为hello的optional对象
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello);
        Optional<Object> o = Optional.of(null);
    }

ofNullable(T value)

    /**
     * ofNullable(T value): 把指定的对象封装为Optional对象,如果它为null,返回一个空Optional对象
     */
    @Test
    public void test2() {
        // 创建一个值为hello的optional对象
        Optional<String> hello = Optional.ofNullable("hello");
        System.out.println(hello);
        Optional<Object> o = Optional.ofNullable(null);
        System.out.println(o);
    }

empty()

    /**
     * empty(): 创建一个空的Optional对象
     */
    @Test
    public void test3() {
        Optional<Object> empty = Optional.empty();
        System.out.println(empty);
    }

 

get()

    /**
     * get(): 如果Optional对象中有值则返回此值,否则抛出NoSuchElementException
     */
    @Test
    public void test4() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.get());
        Optional<Object> empty = Optional.empty();
        System.out.println(empty.get());
    }

 

orElse(T other)

    /**
     * orElse(T other): 如果Optional中有值,则返回此值,否则返回设定默认值
     */
    @Test
    public void test5() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.orElse("world"));
        Optional<Object> empty = Optional.empty();
        System.out.println(empty.orElse("nihao"));
    }

orElseGet(Supplier<? extends T> other)

    /**
     * orElseGet(Supplier<? extends T> other):
     * 如果Optional中有值,则返回此值,否则返回一个由Supplier接口生成的值
     */
    @Test
    public void test6() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.orElseGet(() -> "hello world"));
        Optional<Object> empty = Optional.empty();
        System.out.println(empty.orElseGet(() -> "empty world"));
    }

 

orElseThrow(Supplier<? extends X> exceptionSupplier)

    /**
     * orElseThrow(Supplier<? extends X> exceptionSupplier):
     * 如果Optional有值,则返回值,否则抛出一个由指定的Supplier接口生成的异常
     */
    @Test
    public void test7() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.orElseThrow(() -> {
            return new RuntimeException("异常....");
        }));
        Optional<Object> empty = Optional.empty();
        System.out.println(empty.orElseThrow(() -> {
            return new RuntimeException("异常....");
        }));
    }

filter(Predicate<? super T> predicate)

    /**
     * filter(Predicate<? super T> predicate):
     * 如果Optional中的值满足filter中的条件则返回该值的Optional对象,否则返回一个空的Optional对象
     */
    @Test
    public void test8() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.filter((e) -> e.length() > 1).orElse("world"));
        Optional<String> empty = Optional.empty();
        System.out.println(empty.filter((e) -> e.length() > 1).orElse("empty world"));
    }

 

map(Function<? super T, ? extends U> mapper)

    /**
     * map(Function<? super T, ? extends U> mapper):
     * 如果Optional中有值,则执行提供的Function函数
     */
    @Test
    public void test9() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.map(e -> e.toUpperCase()).orElse("小小"));
        Optional<String> empty = Optional.empty();
        System.out.println(empty.map(e -> e.toLowerCase()).orElse("达达"));
    }

 flatMap(Function<? super T, Optional<U>> mapper)

    /**
     * flatMap(Function<? super T, Optional<U>> mapper)
     * 如果Optional有值,则执行函数,返回一个Optional对象
     */
    @Test
    public void test10() {
        Optional<String> hello = Optional.of("hello");
        System.out.println(hello.flatMap(e -> Optional.of("world")).orElse("error"));
        Optional<String> empty = Optional.empty();
        System.out.println(empty.flatMap(e -> Optional.of("empty")).orElse("empty error"));
    }

isPresent()

    /**
     * isPresent()
     * 判断当前Optional对象是否为空
     */
    @Test
    public void test12() {
        Optional<String> hello = Optional.of("hello");
        System.out.println("hello为空吗?" + hello.isPresent());
        Optional<String> empty = Optional.empty();
        System.out.println("empty为空吗?" + empty.isPresent());
    }

 

ifPresent(Consumer<? super T> consumer)

    /**
     * ifPresent(Consumer<? super T> consumer):
     * 如果Optional对象有值则执行Consumer函数,否则不执行
     */
    @Test
    public void test11() {
        Optional<String> hello = Optional.of("hello");
        hello.ifPresent(e -> System.out.println("I am iron man~"));
        Optional<String> empty = Optional.empty();
        empty.ifPresent(e -> System.out.println("I am iron man~"));
    }

 

 

实战落地

类定义:每个学生能够选择多门必修课和多门选修课

需求:拿到当前选择必修课和选修课的名字(只mock了一条数据,故只拿一个)

@Data
public class StudentDetailVO {

    /*
    学生类
     */
    private String studentId;
    private String studentName;
    // 包含选修课和必修课
    private ClassVO classVO;
    
}

@Data
public class ClassVO {

    /*
    课程类:包含选修课和必修课集合
     */
    private List<MustClassVO> mustClassVOList;
    private List<OptClassVO> optClassVOList;

}

@Data
public class MustClassVO {

    /*
    必修课
     */
    private String className;
    private Integer classId;
    private String examDate;

}

@Data
public class OptClassVO {

    /*
    选修课
     */
    private String className;
    private int classId;

}

public class StudentClassTest {
    public static void main(String[] args) {
        StudentDetailVO studentDetailVO = getStudentDetailVO();
        // 以前写法
        if (Objects.nonNull(studentDetailVO)) {
            ClassVO classVO = studentDetailVO.getClassVO();
            if (Objects.nonNull(classVO)) {
                List<MustClassVO> mustClassVOList = classVO.getMustClassVOList();
                if (!CollectionUtils.isEmpty(mustClassVOList)) {
                    MustClassVO mustClassVO = mustClassVOList.get(0);
                    String className = mustClassVO.getClassName();
                }
            }
        }
        if (Objects.nonNull(studentDetailVO)) {
            ClassVO classVO = studentDetailVO.getClassVO();
            if (Objects.nonNull(classVO)) {
                List<OptClassVO> optClassVOList = classVO.getOptClassVOList();
                if (!CollectionUtils.isEmpty(optClassVOList)) {
                    OptClassVO optClassVO = optClassVOList.get(0);
                    String className = optClassVO.getClassName();
                }
            }
        }

        // Optional写法
        String mClassName = Optional.ofNullable(studentDetailVO)
                .map(StudentDetailVO::getClassVO)
                .map(ClassVO::getMustClassVOList)
                .map((list) -> list.get(0))
                .map(MustClassVO::getClassName)
                .orElse(null);
        String oClassName = Optional.ofNullable(studentDetailVO)
                .map(StudentDetailVO::getClassVO)
                .map(ClassVO::getOptClassVOList)
                .map((list) -> list.get(0))
                .map(OptClassVO::getClassName)
                .orElse(null);

        if (StringUtils.isEmpty(mClassName)) {
            System.out.println("mClassName is null!");
        } else {
            System.out.println("mClassName is not null!");
        }
        if (StringUtils.isEmpty(oClassName)) {
            System.out.println("oClassName is null!");
        } else {
            System.out.println("oClassName is not null!");
        }

    }

    /**
     * mock StudentDetailVO 数据
     * MustClassVO属性为空,OptClassVO属性不为空
     */
    private static StudentDetailVO getStudentDetailVO() {
        StudentDetailVO studentDetailVO = new StudentDetailVO();
        studentDetailVO.setStudentId("123456");
        studentDetailVO.setStudentName("张三");
        ClassVO classVO = new ClassVO();
        List<MustClassVO> list = new ArrayList<>();
        // 传递空MustClassVO对象
        list.add(new MustClassVO());
        classVO.setMustClassVOList(list);
        List<OptClassVO> optClassVOList = new ArrayList<>();
        OptClassVO optClassVO = new OptClassVO();
        optClassVO.setClassId(1);
        optClassVO.setClassName("数学");
        optClassVOList.add(optClassVO);
        classVO.setOptClassVOList(optClassVOList);
        studentDetailVO.setClassVO(classVO);

        return studentDetailVO;
    }
}

 

总结

Optional类的出现为我们在项目中解决和避免NPE异常提供了很好的帮助,灵活运用它的方法能让你的开发效率大大提升。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到