背景
- Optional出现的背景:Java引用中非常容易出现空指针异常,Java8通过将Null所在的变量封装一层,内部仍然利用null来判断是否为空指针,对外屏蔽空指针使用。
- 源码分析Optional封装特点引用对象。
public final class Optional<T> {
/**
* Common instance for {@code empty()}.
*/
private static final Optional<?> EMPTY = new Optional<>();
/**
* If non-null, the value; if null, indicates no value is present
*/
private final T value;
}
OptinalAPI
- empty:对Null引用的封装,调用orElse(),如果为null就返回Other对象
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
public T orElse(T other) {
return value != null ? value : other;
}
@Test
/**
* 封装null
*/
public void testEmpty(){
Optional<String> empty = Optional.empty();
Assert.assertEquals("",empty.orElse(""));
}
- of与ofNullable:工厂方法创建对象
/**
*ofNullabe:创建可以为Null引用的Optional对象
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/**
*of:不能够为Null引用的Optional对象
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
3.map:封装对象调用API
/**
* 对封装对象调用API
*/
public void testInvokeApi(){
Optional<String> message = Optional.of("hello");
Optional<Integer> integer = message.map(item -> {
return item.length();
});
}
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));
}
}
- map方法如果当前Optional有值则返回Empty对象,否则调用方法处理Value并且生成对应Optional
- flatMap:压缩Optional<Optional>为Optinal对象
/**
* 使用flatMap链接Optional对象
*/
public void testFlagMap(){
Optional<String> message = Optional.of("hello");
Optional<Boolean> aBoolean = message.map(s -> s.length()).map(number -> number > 5);
Optional<Person> personOpt = Optional.of(new Person());
//编译错误
//personOpt.map(p->p.car).map(car->car.cardId)
//map->Optional<Optional<String>>
//flatMap->Optional<String>
Optional<String> s = personOpt.flatMap(p -> p.car).flatMap(car -> car.cardId);
}
class Car {
Optional<String> cardId;
}
class Person{
Optional<Car> car;
}
/***
* 源码
*/
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));
}
}
- 源码可以看出flatMap接受的参数必须返回一个Optional<>类型的值,并且源码为直接调用该方法生成对象,而非map的new Optional(U)
- 源码可以看出无论map与flatMap都是在对象为Null的时候生成Empty变量
- filter:过滤特定的值,为null就不过滤
@Test
public void testFilter(){
Optional<String> message = Optional.of("hello");
System.out.println(message.filter(s -> s.length() > 3).orElse("no content"));
}
//源码:
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
- 只有当前Optional为非Empty且满足条件则返回该Optional对象否则返回Empty对象
6.获取值:get/orElse/orElseGet/orElseThrow
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return 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 <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
- get:如果封装值为Null则抛出异常,否则返回封装值
- orELse:如果封装值为Null则返回Other值
- orElseGet:如果封装值为Null则利用other调用生成结果值
- orELseThrow:如果封装值为Null则利用异常生成器生成结果异常