Optional类是Java8为了解决null值判断问题。
Optional对象创建
// 1、创建一个包装对象值为空的Optional对象
Optional<String> optStr = Optional.empty();
// 2、创建包装对象值非空的Optional对象
Optional<String> optStr1 = Optional.of("optional");
// 3、创建包装对象值允许为空的Optional对象
Optional<String> optStr2 = Optional.ofNullable(null);
典型Optional API常用接口
方法名 | 描述 |
---|---|
get() | 主要用于返回包装对象的实际值,但是如果包装对象值为null,会抛出NoSuchElementException异常。 |
isPresent() | isPresent()方法用于判断包装对象的值是否非空 |
ifPresent() | 如果值存在则使用该值调用 consumer , 否则不做任何事情。 |
filter() | 接受参数为Predicate对象,用于对Optional对象进行过滤,如果符合Predicate的条件,返回Optional对象本身,否则返回一个空的Optional对象 |
map() | 参数为Function(函数式接口)对象,map()方法将Optional中的包装对象用Function函数进行运算,并包装成新的Optional对象(包装对象的类型可能改变) |
flatMap() | 跟map()方法不同的是,入参Function函数的返回值类型为Optional类型,而不是U类型,这样flatMap()能将一个二维的Optional对象映射成一个一维的对象 |
orElse() | 如果包装对象值非空,返回包装对象值,否则返回入参other的值(默认值) |
orElseGet() | orElseGet()方法与orElse()方法类似,区别在于orElseGet()方法的入参为一个Supplier对象,用Supplier对象的get()方法的返回值作为默认值 |
orElseThrow() | orElseThrow()方法其实与orElseGet()方法非常相似了,入参都是Supplier对象,只不过orElseThrow()的Supplier对象必须返回一个Throwable异常,并在orElseThrow()中将异常抛出,适用于包装对象值为空时需要抛出特定异常的场景 |
例子一:orElse()
//普通写法
public static String getGender(Teacher teacher)
{
if (null==teacher){
return "Unkown";
}
return teacher.getSex();
}
//使用optional写法 teacher为null或者字段sex为null,返回orElse入参Object;不为空返回teacher对象(这里的teacher经过map处理过)
public static String getSex(Teacher teacher){
return Optional.ofNullable(teacher).map(t->t.getSex()).orElse("Unkown");
}
Optional.ofNullable(reqBO.getUpdateTimeEnd()).orElse(dateFormat.parse("9999-12-31T23:59:59"))
例子二:ifPresent()
//ifPresent() ifPresent()方法内部做了null值检查,调用前无需担心NPE问题。
public static void printName(Teacher teacher ){
Optional.ofNullable(teacher).ifPresent(t-> System.out.println("The Teacher Name is "+teacher.getName()));
}
例子三:Optional的filter(),map()和stream综合运用
public static List<Teacher> getTeachers(){
List<Teacher> teachers=new ArrayList<>();
Teacher teacher1=new Teacher(1,62,"a","男");
Teacher teacher2=new Teacher(2,69,"b","女");
Teacher teacher3=new Teacher(3,71,"c","男");
Teacher teacher4=new Teacher(4,42,"d","女");
Teacher teacher5=new Teacher(5,55,"e","男");
Teacher teacher6=new Teacher(6,31,"f","女");
Teacher teacher7=new Teacher(7,24,"g","男");
Teacher teacher8=new Teacher(8,29,"h","女");
Teacher teacher9=new Teacher(9,21,"i","男");
Teacher teacher10=null;
teachers.add(teacher1);
teachers.add(teacher2);
teachers.add(teacher3);
teachers.add(teacher4);
teachers.add(teacher5);
teachers.add(teacher6);
teachers.add(teacher7);
teachers.add(teacher8);
teachers.add(teacher9);
teachers.add(teacher10);
return teachers;
}
//filter()
public static void filterAge(List<Teacher> teacherList){
//先将传进来的集合用ofNullable创建一个可null的Optional,然后map,将集合转成流,用流的filter()过滤年龄大于30的teacher
//但是发现传进流的filter的teacher也可能出现null,所以在里面将teacher对象转成optional,用optional的filter过滤,然后
//isPresent判断值是否为空
Optional<List<Teacher>> teachers = Optional.ofNullable(teacherList).map(teacher -> teacher.stream().filter(t ->{
//判空
return Optional.ofNullable(t).filter(a->t.getAge() > 30).isPresent();
}).collect(Collectors.toList()));
//遍历
List<Teacher> teachers1 = teachers.get();
System.out.println(teachers1.size());
teachers1.forEach(teacher -> System.out.println(teacher.getName()+" "+teacher.getAge()));
}
List<Teacher> teachers = getTeachers();
filterAge(teachers);
例子四:
@Test
public void aVoid(){
people p=new people("zhangsan","man");
people p1=null;
people p2=new people("","woman");
people p3=new people("lisi","");
// System.out.println(test3(p).getName()+" "+test3(p).getSex());
// System.out.println(test5(p1));
// test6(p);
// test6(p1);
System.out.println(test7(p));
System.out.println(test7(p1));
System.out.println(test7(p3));
// System.out.println(test8(p));
// System.out.println(test8(p1));
// System.out.println(test8(p2));
}
//ofNullable 存在返回对象,不存在返回null
public people test3(people p){
Optional<people> p1 = Optional.ofNullable(p);
return p1.orElse(null);
}
//of 存在返回对象,不存在报空指针异常
public people test4(people p){
Optional<people> p1 = Optional.of(p);
return p1.orElse(null);
}
//orElseGet 存在返回对象,不存在报空指针异常
public people test5(people p){
Optional<people> p1 = Optional.of(p);
return p1.orElseGet(null);
}
//ifPresent 存在才对它做点什么,不存在啥也不干,也不报错
public void test6(people p){
Optional.ofNullable(p).ifPresent(a->{
a.setSex("女");
System.out.println(a.getName()+" "+a.getSex());});
}
//map 存在做点啥,不存在,orElse返回null
public String test7(people p){
Optional<people> p1 = Optional.ofNullable(p);
return p1.map(a->a.getSex()).map(sex->Optional.ofNullable(sex).filter(b->b.length()>0).map(c->c.toUpperCase()).orElse("性别为空")).orElse(null);
}
//map filter
public String test8(people p){
Optional<people> p1 = Optional.ofNullable(p);
return p1.map(b->b.getName()).map(name-> Optional.ofNullable(name).filter(n -> n.length() > 5).orElse("姓名为空或者长度小于等于5")).orElse(null);
}
例子五:
Optional.ofNullable(rcSystemBo.getSysName()).orElseThrow(() -> new ZTBusinessException("系统资源名称不能为空"));
Optional.ofNullable(rcSystemBo.getSysLevel()).orElseThrow(() -> new ZTBusinessException("系统建设级别不能为空"));
Optional.ofNullable(rcSystemBo.getSysUseObject()).orElseThrow(() -> new ZTBusinessException("系统使用对象不能为空"));
Optional.ofNullable(rcSystemBo.getSysUrl()).orElseThrow(() -> new ZTBusinessException("系统访问地址不能为空"));
Optional.ofNullable(rcSystemBo.getSysOrg()).orElseThrow(() -> new ZTBusinessException("系统所属部门不能为空"));
Optional.ofNullable(rcSystemBo.getNetEnvironment()).orElseThrow(() -> new ZTBusinessException("网络环境不能为空"));