- jdk1.8新特性`Optional`的应用
- 概述
- 作用
- 源码分析
- 方法
- 1. `isPresent`:判断查询的类对象是否存在
- 2. ` orElseThrow()`: 相当于` if ... throws`
- 3. `orElse()`:相当于 `if + new (赋值默认值)`
- 4. `oElseGet()`:相当于 `if + 加逻辑处理`
- 应用 :`isPresent`和`orElse()`
- 总结
- `of` 和`offNullAble`区别
- `Optional`中`filter` ,`map`,`flatmap`的认识
- 注意:`filter` ,`map`,`flatmap`都属于`java.util.Stream`的中间方法。但此处的`filter`方法与之前的`stream`流中间方法无关
> 学相伴学习笔记jdk1.8新特性Optional的应用 概述
作用Google Guava项目曾提出用Optional类来包装对象从而解决NullPointerException。受此影响,JDK8的类中也引入了Optional类,在新版的SpringData Jpa和Spring Redis Data中都已实现了对该方法的支持。
- 简化程序逻辑
- 可以修复程序代码中的逻辑判断的问题
package java.util; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; public final class Optional{ private static final Optional> EMPTY = new Optional<>(); private final T value; private Optional() { this.value = null; } public static Optional empty() { @SuppressWarnings("unchecked") Optional t = (Optional ) EMPTY; return t; } private Optional(T value) { this.value = Objects.requireNonNull(value); } public static Optional of(T value) { return new Optional<>(value); } public static Optional ofNullable(T value) { return value == null ? empty() : of(value); } public T get() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; } public boolean isPresent() { return value != null; } public void ifPresent(Consumer super T> consumer) { if (value != null) consumer.accept(value); } public Optional filter(Predicate super T> predicate) { Objects.requireNonNull(predicate); if (!isPresent()) return this; else return predicate.test(value) ? this : empty(); } public Optional map(Function super T, ? extends U> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } } public Optional flatMap(Function super T, Optional> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } } public T orElse(T other) { return value != null ? value : other; } public T orElseGet(Supplier extends T> other) { return value != null ? value : other.get(); } public T orElseThrow(Supplier extends X> exceptionSupplier) throws X { if (value != null) { return value; } else { throw exceptionSupplier.get(); } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Optional)) { return false; } Optional> other = (Optional>) obj; return Objects.equals(value, other.value); } @Override public int hashCode() { return Objects.hashCode(value); } @Override public String toString() { return value != null ? String.format("Optional[%s]", value) : "Optional.empty"; } }
通过源码分析 ,可以知道Optional是一个final类,
- 不能被继承
- 构造函数私有,是单列的对象
- 提供一系列的方法,对其java程序逻辑的判断和优化处理:
| 序号 | 方法 | 方法说明 |
|---|---|---|
| 1 | private Optional() | 无参构造,构造一个空Optional |
| 2 | private Optional(T value) | 根据传入的非空value构建Optional |
| 3 | public static | 返回一个空的Optional,该实例的value为空 |
| 4 | public static | 根据传入的非空value构建Optional,与Optional(T value)方法作用相同 |
| 5 | public static | 与of(T value)方法不同的是,ofNullable(T value)允许你传入一个空的value,当传入的是空值时其创建一个空Optional,当传入的value非空时,与of()作用相同 |
| 6 | public T get() | 返回Optional的值,如果容器为空,则抛出NoSuchElementException异常 |
| 7 | public boolean isPresent() | 判断当家Optional是否已设置了值 |
| 8 | public void ifPresent(Consumer super T> consumer) | 判断当家Optional是否已设置了值,如果有值,则调用Consumer函数式接口进行处理 |
| 9 | public Optional | 如果设置了值,且满足Predicate的判断条件,则返回该Optional,否则返回一个空的Optional |
| 10 | public Optional map(Function super T, ? extends U> mapper) | 如果Optional设置了value,则调用Function对值进行处理,并返回包含处理后值的Optional,否则返回空Optional |
| 11 | public Optional flatMap(Function super T, Optional> mapper) | 与map()方法类型,不同的是它的mapper结果已经是一个Optional,不需要再对结果进行包装 |
| 12 | public T orElse(T other) | 如果Optional值不为空,则返回该值,否则返回other |
| 13 | public T orElseGet(Supplier extends T> other) | 如果Optional值不为空,则返回该值,否则根据other另外生成一个 |
| 14 | public | 如果Optional值不为空,则返回该值,否则通过supplier抛出一个异常 |
被Optional使用的对象,不是null的话就返回true,是null的话则返回false
User user = null; Optionaloptional = Optional.ofNullable(user); if( ! optional.isPresent()){ throw new RuntimeException("用户找不到!!!"); }
2. orElseThrow(): 相当于if ... throws上面的结果其实就出现异常,因为user对象是null。所以optional.isPresent()结果就是false。所以出现异常
判断一个对象是否为null,如果为null,就会抛出异常
public static User getUser(Integer userId){
User user = null;
user = Optional.ofNullable(user)
.orElseThrow(()->new RuntimeException("用户找不到!!!"));//简化 简化 if + throws / if/else
return user;
}
3. orElse():相当于 if + new (赋值默认值)应用场景:它可以简化if+throws场景 + springmvc统一异常处理
判断一个对象是否为null,如果为null,给你默认对象
public static User getUser(Integer userId) {
User user = null;
user = Optional.ofNullable(user).orElse(new User());
return user;
}
4. oElseGet():相当于 if + 加逻辑处理应用场景:if+throws场景 + springmvc统一异常处理
相当于加了一个匿名内部类,里面可以写你想要进行的处理逻辑
user = Optional.ofNullable(user).orElseGet(()->{
User user1 = new User();
// 增加各种处理和逻辑
return user1;
});
应用 :isPresent和orElse()应用场景:例如数据查询是有值的,有些是没有值,但是我需要统计那些错误访问数据。
场景:当用户第一次注册给其设置默认昵称和密码:
User user = new User();
user.setNickname(Optional.ofNullable(user.getNickname()).orElse("学生"));
user.setPassword(Optional.ofNullable(user.getPassword()).orElse("123456"));
总结
of 和offNullAble区别
@Test
public void m1(){
Optional fullName2 = Optional.ofNullable(null);
Optional fullName = Optional.of(null);
}
- 相同点
- 两者都是去创建Optional对象
- 两者都是给value成员变量赋值
问题: 为什么of方法会报空指针异常
去of源码查看其创建optional对象的代码:
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
点击requireNonNull查看:
public staticT requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); // 如果value是null,就出现空指针异常 return obj; }
由此我们发现:of方法如果传入的对象为null,就直接返回NullPointerException
而ofNullAble源码则是当传值为空的时候,直接给创建一个空对象:
public staticOptional中filter ,map,flatmap的认识 注意:filter ,map,flatmap都属于java.util.Stream的中间方法。但此处的filter方法与之前的stream流中间方法无关Optional ofNullable(T value) { return value == null ? empty() : of(value); }
它在Optional中的存在,其实还是去解决一个程序开发过程中集合为空问题。
作用:集合中的元素如果不为空,就直接用filter/map/flatmap处理,
如果为空给要么抛出异常。要么默认初始化
实例:
Listusers = null; users = Optional.ofNullable(users) // 1: 创建一Optional并给Optional的value赋值null .filter((u) -> u.get(0).getId().equals(1))// 2: 调用的Optional中filter内部出现空异常,不报错,赋值空的Optional对象 .orElse(new ArrayList<>()); // 3: 如果前面代码是空对象,则初始化集合 System.out.println(users);



