什么是 Optional
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。
Optional 能解决什么
Optional提供很多有用的方法,这样我们就不用显式进行空值检测,很好的解决空指针异常
Optional 怎么用
创建Optional 三种方法
//创建一个一定是非空值Optional容器
Optional<Car> emptyCar = Optional.empty();
//创建一个一定是非空值Optional容器(传入的对象不可以为null,否则抛出NullPointerException)
Optional<Car> notNullCar = Optional.of(car);
//创建一个可能是空也可能不为空的Optional容器(传入的对象可以为null)
Optional<Car> allCar = Optional.ofNullable(car);
常用API
1、isPresent() //有值则返回true
2、get(): //值存在时返回值,否则抛出一个NoSuchElement异常(所以调这个,一般先判断上面方法返回是否为true)
3、orElse(T other) //值存在时返回值,否则返回一个默认值
4、ifPresent(Consumer<T> block) //会在值存在的时候执行给定的代码块
5、orElseThrow(Supplier<? extends X> exceptionSupplier) //与get()类似,不同的是可以自定义异常类型
6、orElseGet(Supplier<? extends T> other) //orElse方法的延迟调用版,Supplier方法只有在Optional对象不含值时才执行调用
7、map/flatMap/filter //与Stream中用法类似 //与Stream中用法类似
Demo
public static void main(String[] args) {
//1、创建Optional实例,传入的对象不能为null
Optional<String> nameOptional = Optional.of("张三");
//2、创建Optional实例,传入对象可以为null,也可以不为null
Optional emptyOptional = Optional.ofNullable(null);
//3、isPresent方法(布尔值)用来检查Optional实例是否有值。
if (nameOptional.isPresent()) {
//调用get()返回Optional值。
System.out.println("1、" + nameOptional.get());
}
try {
//4、在Optional实例上调用get()抛出NoSuchElementException。
System.out.println("2、" + emptyOptional.get());
} catch (NoSuchElementException ex) {
System.out.println("3、异常" + ex.getMessage());
}
//5、如果Optional值不为空,lambda表达式会处理并在其上执行操作。(这里x代表就是nameOptional中的对象)
nameOptional.ifPresent((x) -> {
System.out.println("4、字符串长度为: " + x.length());
});
//6、如果有值orElse方法会返回Optional实例,没值则返回当前值
System.out.println("5、"+ emptyOptional.orElse("如果是空容器则返回李四"));
System.out.println("6、"+nameOptional.orElse("如果是空容器则返回王五"));
//7、orElseGet与orElse类似,区别在于传入的参数不同,一个是直接传入对象,这个是传入Supplier函数式接口
System.out.println("7、" + emptyOptional.orElseGet(() -> {return "李" + "四";}));
System.out.println("8、" + nameOptional.orElseGet(() -> "王五"));
try {
//8、如果是空容器,则可以抛出自定义异常。
emptyOptional.orElseThrow(() -> new NullPointerException("空容器异常"));
} catch (Throwable ex) {
System.out.println("9、" + ex.getMessage());
}
//9、这里入参是Function,所以可以转换容器中的对象 好比将String对象转为Integer对象
Optional<String> ageOptional = Optional.of("10");
Optional<Integer> age = ageOptional.map((o) -> Integer.parseInt(o));
//10、flatMap与map(Funtion)非常相似,不同在于 map返回可以将String对象转为Integer对象,但flatMap转换后一定还是String对象
Optional<String> upperName = nameOptional.flatMap((o) -> Optional.of(o.toUpperCase()));
//11、filter方法检查Optiona值是否满足给定条件。如果满足返回Optional实例值,否则返回空Optional。
Optional<String> conditionName = nameOptional.filter((o) -> o.length() > 6);
System.out.println("10、" + conditionName.orElse("conditionName容器的名字长度小于6位"));
//12、另一个示例,Optional满足给定条件。
Optional<String> longName = Optional.of("名字天下第一长");
Optional<String> shortName = longName.filter((o) -> o.length() > 6);
System.out.println("11、" + shortName.orElse("longName容器的名字长度小于6位"));
}
结果
总结:将数据校验这部分 由3行代码 缩减为 1行