Optional 中的方法:
- Optional.empty()
- Optional of(obj)
- Optional ofNullable(obj)
- public T get()
- public boolean isPresent()
- public T orElse(T other)
- public T orElseGet(Superlier<? extends T> other)
- public void ifPresent(Consumer<? super T> consumer)
- public <U> Optional<U> map(Function<? super T, ? extends U> mapper)
- public Optional<T> filter(Predicate<? super T>) predicate
- public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
- public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws x
注意:每一个被调用的方法都只对他前面的结果负责
(1)Optional.empty()
三种构造方式之一:
重新new一个Optional(),并返回
源码:
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private static final Optional<?> EMPTY = new Optional<>();
(2)Optional.of(obj)
三种构造方式之一:
将数据 转换成 Optional类型(获取具有指定类型的指定值的Optional类的实例)
要求传入参数非空,否则会报NullPointerException
可通过 .get()方法 获取原值
源码:
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
应用场景:
- 非常明确 将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时
比如obj是一个刚new出来的对象,或者是一个非null常量。
- 想为 obj 断言非 null 时
比如 想要 obj 一旦为 null 就立即报告 NullPointerException 异常, 而不是隐藏
(3)Optional.ofNullable(obj)
三种构造方式之一:
功能与Optional.of()相同,底层也应用了Optional.of()方法。
但是对 null 类型进行了判断,如果为null,则方法内部会 通过 Optional.empty()方法重新 new 一个新的空的 Optional进行返回
源码:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
(4)get()
获取调用对象原有值
调用对象为空,则直接返回报错 NoSuchElementException() 信息为 No value present
源码:
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
注意:
没有 isPresent()
作铺垫的 get()
调用在 IntelliJ IDEA 中会收到告警
Reports calls to java.util.Optional.get() without first checking with a isPresent() call if a value is available. If the Optional does not contain a value, get() will throw an exception.
调用 Optional.get() 前不事先用 isPresent() 检查值是否可用. 假如 Optional 不包含一个值, get() 将会抛出一个异常
(5)isPresent()
判断当前对象是否存在,返回 boolean 值
本质上 isPresent() 与 obj != null 无任何分别
源码:
public boolean isPresent() {
return value != null;
}
应用:
假定已有一个实例 Optional<User> user
boolean flag = user.isPresent();
(6)orElse()
存在即返回, 不存在则提供默认值
调用对象非空,则返回该对象
调用对象为空,则返回指定值
源码:
public T orElse(T other) {
return value != null ? value : other;
}
应用:
import org.junit.Test;
import java.util.Optional;
public class OptionalAdvanced {
public final String nullStr = null;
public final LocalBean localBean = null;
@Test
public void testOrElse() {
// 可以 替换 nullStr.isPresent() ? nullStr : "user orElse() print content";
String ofNullableStr = Optional.ofNullable(nullStr).orElse("user orElse() print content");
System.out.println(ofNullableStr);
// 可以替换 localBean.isPresent() ? localBean.get() : new LocalBean();
LocalBean localBean = Optional.ofNullable(this.localBean).orElse(new LocalBean());
System.out.println(localBean);
}
}
(7)orElseGet()
存在即返回,不存在则由函数来产生
源码:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
应用:
import org.junit.Test;
import java.util.Optional;
public class OptionalAdvanced {
@Test
public void testOrElseGet() {
LocalBean backBean = Optional.ofNullable(this.localBean).orElseGet(() -> this.giveBean());
System.out.println(backBean);
}
public LocalBean giveBean() {
return new LocalBean();
}
}
(8)ifPresent(Consumer<? super T> consumer)
存在才对它做点什么
源码:
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
应用:
import org.junit.Test;
import java.sql.SQLOutput;
import java.util.Optional;
public class OptionalAdvanced {
public final LocalBean localBean = null;
@Test
public void testIfPresent() {
// 可替换此类型的判断代码
//if (user.isPresent())
// System.out.println(user.get());
Optional<LocalBean> fullBean = Optional.ofNullable(new LocalBean());
fullBean.ifPresent(System.out::println);
Optional<LocalBean> nullBean = Optional.ofNullable(this.localBean);
nullBean.ifPresent(System.out::println);
}
}
(9)map() 函数
获取对象中的某个字段的值
源码:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
应用:
import org.junit.Test;
import java.sql.SQLOutput;
import java.util.Locale;
import java.util.Optional;
public class OptionalAdvanced {
public final String nullStr = null;
public final LocalBean nullBean = null;
@Test
public void testMap() {
// 对象为空
LocalBean nullBean = null;
String there_is_no_name = Optional.ofNullable(nullBean).map(bean -> bean.getName()).orElse("there is no name");
System.out.println(there_is_no_name); // there is no name
// 属性为空
LocalBean emptyBean = new LocalBean();
String this_is_empty_bean = Optional.ofNullable(emptyBean).map(bean -> bean.getName()).orElse("there is no name");
System.out.println(this_is_empty_bean); // there is no name
// 对象、属性 均非空
LocalBean fullBean = new LocalBean();
fullBean.setName("kobe");
Optional<LocalBean> fullBeanOptional = Optional.ofNullable(fullBean);
String here_has_name = fullBeanOptional.map(bean -> bean.getName()).orElse("there is no name");
System.out.println(here_has_name); // kobe
// 调用其他函数
fullBeanOptional.map(bean -> bean.getName()).ifPresent(System.out::println); // kobe
// map 可能无限级联的, 比如再深一层, 获得用户名的大写形式
String upperCase = fullBeanOptional.map(bean -> bean.getName()).map(name -> name.toUpperCase(Locale.ROOT)).orElse("there is no name");
System.out.println(upperCase); // KOBE
}
}
Groovy 提供了一种安全的属性/方法访问操作符
?.
应用:
user?.getUsername()?.toUpperCase();
Swift 也有类似的语法, 只作用在 Optional 的类型上.
(10)filter()
把不符合条件的值变为 empty()
源码:
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
应用:
@Test
public void testFlatMap() {
// 对象、属性 均非空
LocalBean fullBean = new LocalBean();
fullBean.setAge(22);
Optional<LocalBean> fullBeanOptional = Optional.ofNullable(fullBean);
LocalBean fullBack = fullBeanOptional.filter(bean -> bean.getAge() == 22).orElse(new LocalBean());
System.out.println(fullBack); // LocalBean(age=22, name=null, address=null)
LocalBean emptyBack = fullBeanOptional.filter(bean -> bean.getAge() > 22).orElse(new LocalBean());
System.out.println(emptyBack); // LocalBean(age=null, name=null, address=null)
}
(11)flatMap()
总是与
map()
方法成对的,map中获取的返回值自动被Optional包装,即 返回值 ----> Optional<返回值>
flatMap中返回值保持不变,但必须是Optional类型,即Optional<返回值> -> Optional<返回值>
源码:
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
应用:
@Test
public void testFlatMap() {
// 对象、属性 均非空
LocalBean fullBean = new LocalBean();
fullBean.setAge(22);
Optional<LocalBean> fullBeanOptional = Optional.ofNullable(fullBean);
Optional<Integer> integer = fullBeanOptional.flatMap(OptionalAdvanced::getOrderNumber);
System.out.println(integer);
}
private static Optional<Integer> getOrderNumber(LocalBean fullBean) {
return Optional.ofNullable(fullBean).map(bean -> bean.getAge());
}
(12)orElseThrow()
有值时直接返回, 无值时抛出想要的异常
源码:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
应用:
@Test
public void testOrElseThrow() {
// 对象、属性 均非空
LocalBean nullBean = null;
Optional<LocalBean> nullBeanOptional = Optional.ofNullable(nullBean);
LocalBean xinxicuowu = nullBeanOptional.orElseThrow(() -> new RuntimeException("xinxicuowu"));
System.out.println(xinxicuowu);
}
总结:
使用
Optional
时尽量不直接调用Optional.get()
方法,Optional.isPresent()
更应该被视为一个私有方法, 应依赖于其他像Optional.orElse()
,Optional.orElseGet()
,Optional.map()
等这样的方法.Optional 的方法中基本都是内部调用
isPresent()
判断, 真时处理值, 假时什么也不做.