背景
大家都知道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 后查看