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