1. Optional中包含一个可以为空的对象,应该在所有可能为空的地方都加上Optional作为返回值。强迫调用方自行判断是否为空。自己因为老是忘记判断是否为null而导致空指针。
2. Optional之前自己最习惯的用法是先判断是否是ifPresent,然后去进行下一步操作。看了代码之后,发现也可以通过orElse来设定默认值,或者是通过orElseThrow来抛出为空时的异常。
3. 看了Effective java,容器类的集合不应该返回Optional,直接返回一个空集合更加合适。
Optional是一个包含了可能为空的对象的容器对象,如果值存在(isPresent()),可以利用get()获取到
-----------------------
第一个对象:
private static final Optional> EMPTY = new Optional<>();
一个空对象
-------------------------
private final T value;
非空,get()获取到的就是这个对象
---------------------------
private Optional() {
this.value = null;
}
构造一个空的实例
-----------------------------
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;
return t;
}
返回一个空的Optional对象,即EMPTY
------------------------------
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
这里只能传入一个非空的对象,给value赋值
------------------------------
public static Optional of(T value) {
return new Optional<>(value);
}
这里只能传入非空对象,返回一个Optional对象,且该对象的isPresent()是为true
--------------------------------
public static Optional ofNullable(T value) {
return value == null ? empty() : of(value);
}
与上面的方法类似,这里传入的是可以为空的对象,如果为空返回empty(),否则与of方法相同
-----------------------------------
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
获取value,如果为空,跑出异常,否则返回value。
补充:
@NotNull
@Contract(pure=true):
可参考文档
https://ice1000.org/2017/01/07/JBAnnotations2/
例子:
@NotNull
@Contract(value = "_, _ -> !null", pure = true)
返回值为非null,因此@NotNull,
不管传进来任何值,都不会返回null,因此value是_, _ -> !null,pure=true说明是纯函数。纯函数这里理解为,对于特定的输入,都将产生对应的唯一输出,且不会影响别的东西。
-------------------------------------
public boolean isPresent() {
return value != null;
}
判断value是否为null
---------------------------------------
public void ifPresent(Consumer super T> consumer) {
if (value != null)
consumer.accept(value);
}
如果value不存在,调用传入的consumer,
补充:
Consumer接口:
void accept(T t);
调用accept方法
default Consumer
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
传入的after不能为空,先调用默认的accept,然后调用after实现的accept方法
Consumer接口上有个注解:@FunctionalInterface
https://www.cnblogs.com/chenpi/p/5890144.html
函数式接口,即接口里边只有一个抽象方法,用于编译级错误检查,接口不符合函数式接口定义,就会报错。函数式接口里边还可以包含默认方法、静态方法、java.lang.Object里边的public方法
---------------------------------------------------
public Optional filter(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
如果value不为null切符合predicate,返回这个Optional对象,否则返回empty()
-----------------------------------------------------
public Optional map(Function super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
如果value不为null,调用传入的mapper方法,然后返回Optional.ofNullable(mapper结果),否则返回empty();
--------------------------------------------------
public Optional flatMap(Function super T, Optional> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
这个方法与上一个类似,但是mapper本身的返回就是在optional中了。
--------------------------------------------------------
public T orElse(T other) {
return value != null ? value : other;
}
传入参数非空,返回也非空,value不为null返回value,value为null,返回输入的other
-------------------------------------------------------
public T orElseGet(Supplier extends T> other) {
return value != null ? value : other.get();
}
与上一个方法类似,但是传入的是实现了接口Supplier的
----------------------------------------------------
public T orElseThrow(Supplier extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
value为null抛出异常,否则返回value
---------------------------------------------
@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);
}
相等
其他方法略。