Optional
Optional 类(java.util.Optional) 是一个容器类
,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
源码:
public final class Optional<T> {
/**
* 调用私有的空构造方法
*/
private static final Optional<?> EMPTY = new Optional<>();
/**
* If non-null, the value; if null, indicates no value is present
*/
private final T value;
/**
* 构造方法:构造一个容器值value为空的Optional对象
*/
private Optional() {
this.value = null;
}
/**
*静态方法:构造一个容器值value为空的Optional对象
*如果不为空,则
*/
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
/**
* 构造方法:构造一个容器值value为入参的Optional对象
* T value 不能为空(requireNonNull)
*/
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
/**
* 静态方法:调用私有的有参构造方法,构造一个容器值value为入参的Optional对象
* T value 不能为空(requireNonNull)
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
/**
* 二者折中,参数 T value可以为空,也可以不为空,如果为空,则构造一个容器值value为空的Optional对象
*如果不为空,则构造一个容器值value为入参的Optional对象
*/
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/**
*获取容器的value值,如果为空则抛出异常NoSuchElementException
*/
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
/**
* 判断容易value值
*/
public boolean isPresent() {
return value != null;
}
/**
* 如果非空,则执行函数式接口Consumer的accept
*/
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
/**
* If a value is present, and the value matches the given predicate,
* return an {@code Optional} describing the value, otherwise return an
* empty {@code Optional}.
*
* @param predicate a predicate to apply to the value, if present
* @return an {@code Optional} describing the value of this {@code Optional}
* if a value is present and the value matches the given predicate,
* otherwise an empty {@code Optional}
* @throws NullPointerException if the predicate is null
*/
public Optional<T> filter(Predicate<? super T> predicate) {
Objects.requireNonNull(predicate);
if (!isPresent())
return this;
else
return predicate.test(value) ? this : empty();
}
/**
* 参数是个Function,如果value不存在,调用empty()返回一个值为空的Optional
* 如果value存在,将Function的apply(value)作为参数执行ofNullable,返回一个新的
* Optional
*/
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));
}
}
/**
* If a value is present, apply the provided {@code Optional}-bearing
* mapping function to it, return that result, otherwise return an empty
* {@code Optional}. This method is similar to {@link #map(Function)},
* but the provided mapper is one whose result is already an {@code Optional},
* and if invoked, {@code flatMap} does not wrap it with an additional
* {@code Optional}.
*
* @param <U> The type parameter to the {@code Optional} returned by
* @param mapper a mapping function to apply to the value, if present
* the mapping function
* @return the result of applying an {@code Optional}-bearing mapping
* function to the value of this {@code Optional}, if a value is present,
* otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is null or returns
* a null result
*/
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));
}
}
/**
* 如果value存在则返回,如果不存在则放回入参 other
*/
public T orElse(T other) {
return value != null ? value : other;
}
/**
* Return the value if present, otherwise invoke {@code other} and return
* the result of that invocation.
*
* @param other a {@code Supplier} whose result is returned if no value
* is present
* @return the value if present otherwise the result of {@code other.get()}
* @throws NullPointerException if value is not present and {@code other} is
* null
*/
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
/**
* Return the contained value, if present, otherwise throw an exception
* to be created by the provided supplier.
*
* @apiNote A method reference to the exception constructor with an empty
* argument list can be used as the supplier. For example,
* {@code IllegalStateException::new}
*
* @param <X> Type of the exception to be thrown
* @param exceptionSupplier The supplier which will return the exception to
* be thrown
* @return the present value
* @throws X if there is no value present
* @throws NullPointerException if no value is present and
* {@code exceptionSupplier} is null
*/
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
/**
* Indicates whether some other object is "equal to" this Optional. The
* other object is considered equal if:
* <ul>
* <li>it is also an {@code Optional} and;
* <li>both instances have no value present or;
* <li>the present values are "equal to" each other via {@code equals()}.
* </ul>
*
* @param obj an object to be tested for equality
* @return {code true} if the other object is "equal to" this object
* otherwise {@code false}
*/
@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);
}
/**
* Returns the hash code value of the present value, if any, or 0 (zero) if
* no value is present.
*
* @return hash code value of the present value or 0 if no value is present
*/
@Override
public int hashCode() {
return Objects.hashCode(value);
}
/**
* Returns a non-empty string representation of this Optional suitable for
* debugging. The exact presentation format is unspecified and may vary
* between implementations and versions.
*
* @implSpec If a value is present the result must include its string
* representation in the result. Empty and present Optionals must be
* unambiguously differentiable.
*
* @return the string representation of this instance
*/
@Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
}
栗子:
public class OptionalTest {
public static void main(String[] args) {
Optional<String> opt1=Optional.of("hello"); //value: hello
System.out.println(opt1.get());
//Optional<String> opt2=Optional.of(null); //NullPointerException
//Optional<String> opt3=Optional.empty(); //NullPointerException
//opt3.get(); //NoSuchElementException("No value present")
opt1.ifPresent(e-> System.out.println(new StringBuffer(e).append(" world")));//hello world
//-------------通过Optional避免空指针------------------:
String s=null;
Optional<String> opt4=Optional.ofNullable(s);
//one:
if (opt4.isPresent()){
System.out.println(s+": 非空");
}
//two:
opt4.ifPresent(e-> System.out.println(s+": 非空"));
// orElse 如果value存在则返回,如果不存在则放回入参
Optional<String> opt5=Optional.empty();
System.out.println(opt5.orElse("value为空")); //value为空
Optional<String> opt6=Optional.of("syc");
System.out.println(opt6.orElse("value为空")); //syc
// orElseGet 参数是个Supplier
Optional<String> opt7=Optional.empty();
String value = opt7.orElseGet(() -> new StringBuffer("value为空").toString());
System.out.println(value);//value为空
//map
Optional<String> opt8=Optional.of(" ni hao ");
Optional<String> o = opt8.map(e -> e + "syc");
System.out.println(o.get());// ni hao syc
}
}
还有OptionalDouble,OptionalInt,OptionalLong等,基本与Optional大同小异
给个饭钱?
- Post link: http://sovzn.github.io/2022/09/04/Optional/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues