java 8-Optional


開発の過程で、私達はよくNull PointerExceptionに出会います。Null Point Exceptionのこの異常を避けるために、コードの中で空ではないと判断して、コードの膨張を引き起こし、可読性に影響を与えます。このため、Java 8には新しいクラスjava.util.Optionalが導入されています。これはOptional値をカプセル化したクラスで、空の場合に処理することができます。Optionalには二つのメンバーのオブジェクトがあります。一つはEMPTY、一つはvalueです。EMPTYはOptionalタイプで、valueはT汎型です。
empty
空いているOptionalを作成します。ソースから見れば、このvalueはnullです。
public static Optional empty() {
    @SuppressWarnings("unchecked")
    Optional t = (Optional) EMPTY;
    return t;
}

private static final Optional> EMPTY = new Optional<>();

private Optional() {
    this.value = null;
}
保存先
指定された値からOptionalを作成します。ソースからは、空ではないと判断されます。だから、この方法がnullに伝わったら、Null PointerExceptionを投げます。
public static  Optional of(T value) {
    return new Optional<>(value);
}
private Optional(T value) {
    this.value = Objects.requireNonNull(value);
}
ONullable
空いているOptionalを許諾すれば、ONullableが使えます。ソースからは、空の場合は、emptyメソッドを呼び出すことができますが、空ではない場合は、メソッドを呼び出します。
public static  Optional ofNullable(T value) {
    return value == null ? empty() : of(value);
}
isPresent
valueが空かどうかを判断して、空のためにtrueに戻りません。空のためにfalseに戻ります。
public boolean isPresent() {
    return value != null;
}
map
指定されたオブジェクトをマッピングしてOptionalに戻ります。ソースから见れば、まずmapperが空かどうかを判断します。空ではなく、valueが空かどうかを判断します。空のために、直接emptyに戻ります。空ではなく、Functionalの戻り値でOptionalを作成します。
public Optional map(Function super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value));
    }
}
flatMap
mapのように、戻ってくるのはOptionalタイプであり、複数のパッケージのオブジェクトがある場合には、この方法を用いることができます。たとえばPerson類、Personにはchildメンバー変数があり、Personオブジェクトでもあります。このようにpersonのnameを取得することができます。optPerson.flatMap(Person::getOptChild).map(Person::getName)
public Optional flatMap(Function super T, Optional> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value));
    }
}
get
Optionalのvalueを返します。もしvalueが空だったら、NoSuchElement Exceptionを投げます。
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}
オルルス
もしvalueが空ではないなら、valueに戻ります。そうでなければ、デフォルトの値に戻ります。
public T orElse(T other) {
    return value != null ? value : other;
}
オルルスGet
これはorElseと似ていますが、空いている時に戻ります。Supplierのget方法です。
public T orElseGet(Supplier extends T> other) {
    return value != null ? value : other.get();
}
orElseThrow
もしvalueが空であれば、例外を投げます。この異常には伝えられたSupplierのgetが指定されています。
public  T orElseThrow(Supplier extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}
ifPresent
valueが存在するとConsmerのacceptメソッドを呼び出します。
public void ifPresent(Consumer super T> consumer) {
    if (value != null)
        consumer.accept(value);
}
filter
Predicateのtestメソッドが存在し、現在のOptionalを返すと、空のOptionalオブジェクトに戻ります。
public Optional filter(Predicate super T> predicate) {
    Objects.requireNonNull(predicate);
    if (!isPresent())
        return this;
    else
        return predicate.test(value) ? this : empty();
}