Optional用法实例一
数据准备
List<Student> list = new ArrayList<>();
list.add(new Student("王一", 21, "11", 1, new BigDecimal("193.0")));
list.add(new Student("郑二", 22, "22", 0, new BigDecimal("171.0")));
list.add(new Student("张三", 23, "33", 1, new BigDecimal("180.1")));
list.add(new Student("李四", 24, "44", 0, new BigDecimal("183.2")));
list.add(new Student("赵五", 25, "55", 1, new BigDecimal("178.3")));
orElseGet
简单的示例
需求:
- 假定List值中没有null,Student中可以有null
- 假定有相同的只返回找到的第一个
- 找年龄为26的数据,没有就找分数为66的数据,再没有就找身高最高的数据,再没有返回null
- 注:orElse不论optional有没有值的时候都会执行;orElseGet只会在optional为空时执行
- 注: [-128,127]非此区间内不要使用==去比较
Student student =
list.stream()
.filter(a -> 26 == a.getAge()).findFirst()
.orElseGet(
() -> list.stream().filter(b -> "66".equals(b.getScore())).findFirst()
.orElseGet(
() -> list.stream().max(Comparator.comparing(Student::getHeight, BigDecimal::compareTo))
.orElse(null)
)
);
会出现的异常问题
当前面提到的条件中有null值存在的话会出现NPE。
解决措施一
先整体过滤,在此基础上再进行查找操作。
List<Student> collect = list.stream()
.filter(a -> a.getAge() != null && a.getScore() != null && a.getHeight() != null)
.collect(Collectors.toList());
此方法的问题:只有都满足条件是才保留,其余情况都被过滤。会导致一些有用的数据被过滤掉,从而最终得到的结果不符合需求本身。
解决措施二
每次进行条件判断前先验证。
此方法中涉及到对null的排序问题看此处链接排序
Student student =
list.stream()
.filter(
a -> a.getAge() != null && 26 == a.getAge()
).findFirst()
.orElseGet(
() -> list.stream().filter(
b -> b.getScore() != null && "66".equals(b.getScore())
).findFirst()
.orElseGet(
() -> list.stream().max(
Comparator.comparing(Student::getHeight, Comparator.nullsFirst(BigDecimal::compareTo))
)
.orElse(null)
)
);