まず、両方のメソッドの宣言を確認します。
1)OrElse:ロジックを実行し、結果を引数として渡します。
public T orElse(T other) {
return value != null ? value : other;
}
2)OrElseGet:オプション内の値がnullの場合にロジックを実行します
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
上記の宣言に関するいくつかの説明:
「Optional.orElse」の引数は、オプションのオブジェクトの値(null、空、または値付き)に関係なく常に実行されます。「Optional.orElse」を使用する際は、常に上記の点を考慮してください。そうでない場合、「Optional.orElse」の使用は、次の状況で非常に危険になる可能性があります。
リスク-1)ログの問題: orElse内のコンテンツにログステートメントが含まれている場合:この場合、毎回ログに記録することになります。
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
リスク-2)パフォーマンスの問題: orElse内のコンテンツに時間がかかる場合:時間のかかるコンテンツは、任意のI / O操作のDB呼び出し、API呼び出し、ファイルの読み取りです。そのようなコンテンツをorElse()に入れると、システムは無駄なコードを実行することになります。
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
リスク3)違法な状態またはバグの問題: orElse内のコンテンツが一部のオブジェクトの状態を変更している場合:別の場所で同じオブジェクトを使用している可能性があります。
List<Model> list = new ArrayList<>();
Optional.of(getModel())
.map(x -> {
})
.orElse(get(list));
get(List < String > list) {
log.error("No Data found, Returning default");
list.add(defaultValue);
return defaultValue;
}
では、いつorElse()を使用できますか?
デフォルト値が定数オブジェクトである列挙型の場合は、orElseを使用することをお勧めします。上記のすべてのケースで、Optional.orElse()の代わりにOptional.orElseGet()(Optionalに空でない値が含まれている場合にのみ実行される)を使用できます。なぜ??orElseでは、デフォルトの結果値を渡しますが、orElseGetでは、Supplierを渡し、Optionalの値がnullの場合にのみ、Supplierのメソッドを実行します。
これからの重要なポイント:
- ログステートメントが含まれている場合は、「Optional.orElse」を使用しないでください。
- 時間のかかるロジックが含まれている場合は、「Optional.orElse」を使用しないでください。
- オブジェクトの状態が変化する場合は、「Optional.orElse」を使用しないでください。
- 定数、列挙型を返す必要がある場合は、「Optional.orElse」を使用します。
- 1、2、および3番目のポイントで述べた状況では、「Optional.orElseGet」を優先します。
私はこれを中程度のブログのポイント2(「Optional.map/Optional.orElse」!=「if/else」)で説明しました。コーダーとしてではなくプログラマーとしてJava8を使用する
orElseGet
値を指定しない場合にのみサプライヤーを呼び出すときに使用するためです。