Javaオプション – orElse()vs orElseGet()
1.はじめに
Optional
のAPIには通常、混乱を招く可能性がある2つのメソッド、
__ orElse()
と
orElseGet()__があります。
このクイックチュートリアルでは、この2つの違いを見て、それぞれをいつ使用するかを探ります。
2.署名
まず署名を見て基本から始めましょう。
public T orElse(T other)
public T orElseGet(Supplier<? extends T> other)
明らかに、
__ orElse()は任意の型のパラメータを取ります
T
は他の
orElseGet()型は
T
型のオブジェクトを返す
Supplier__型の関数型インタフェースを受け入れます。
今、彼らのhttps://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElse-T-[Javadocs]に基づいて:
-
orElse()
:存在すれば値を返し、そうでなければ
other
を返します -
orElseGet():
は、存在すれば値を返し、そうでなければ呼び出し
__other
__そして呼び出しの結果を返す
3.違い
この単純化された定義に少し混乱するのは簡単なので、もう少し詳しく調べて、実際の使用シナリオを見てみましょう。
3.1.
orElse()
/java-logging-intro[logger]リンクが正しく設定されていると仮定して、簡単なコードを書くことから始めましょう。
String name = Optional.of("baeldung")
.orElse(getRandomName());
__getRandomName()
が
List <String>
of
namesからランダムな
__name
__を返すメソッドであることに注意してください。
public String getRandomName() {
LOG.info("getRandomName() method - start");
Random random = new Random();
int index = random.nextInt(5);
LOG.info("getRandomName() method - end");
return names.get(index);
}
コードを実行すると、以下のメッセージがコンソールに表示されます。
getRandomName() method - start
getRandomName() method - end
コード実行の最後に、変数
__name
will hold
“ baeldung”
__があります。
これにより、空でない
Optional
がある場合でも、
orElse()
の** パラメータが評価されることを簡単に推測できます。
3.2.
orElseGet()
それでは、
orElseGet()
を使って同様のコードを書いてみましょう。
String name = Optional.of("baeldung")
.orElseGet(() -> getRandomName());
上記のコードは
__getRandomName()
__methodを呼び出しません。
引数として渡されたS
__upplier
methodは、
an Optional
__valueが存在しない場合にのみ実行されることを忘れないでください(Javadocより)。
したがって、
__orElseGet()
を使用すると、ランダムな
name__の計算にかかる時間を節約できます。
[[jmh benchmark]]
4.パフォーマンスへの影響の測定
それでは、パフォーマンスの違いも理解するために、
JMH
を使って実際の数値を見てみましょう。
@Benchmark
@BenchmarkMode(Mode.AverageTime)
public String orElseBenchmark() {
return Optional.of("baeldung").orElse(getRandomName());
}
そして
orElseGet()
:
@Benchmark
@BenchmarkMode(Mode.AverageTime)
public String orElseGetBenchmark() {
return Optional.of("baeldung").orElseGet(() -> getRandomName());
}
ベンチマークメソッドを実行すると、次のようになります。
Benchmark Mode Cnt Score Error Units
orElseBenchmark avgt 20 60934.425 ± 15115.599 ns/op
orElseGetBenchmark avgt 20 3.798 ± 0.030 ns/op
ご覧のとおり、このような単純なユースケースのシナリオでも、パフォーマンスへの影響はかなり大きいかもしれません。
上記の数値は多少異なる可能性がありますが、**
orElseGet()
は、この例では明らかに____orElse()を上回っています。
Afternl、
__orElse()は、実行ごとに
getRandomName()
__methodの計算を行います。
[[why bother]]
5.何が重要ですか?
パフォーマンスの面とは別に、他に考慮する必要がある要素は次のとおりです。
-
メソッドが何らかの追加ロジックを実行する場合はどうなりますか?例えば。作る
いくつかのDB挿入または更新
**
__orElse()
__parameterにオブジェクトを代入しても
String name = Optional.of("baeldung").orElse("Other")
理由はありませんが、
__“ Other”
__オブジェクトを作成中
そのため、
__orElse()
or
__orElseGet()の間で、ニーズに応じて慎重に決定することが重要なのです。直接。**
6.まとめ
この記事では、
__Optional orElse()
と
OrElseGet()
__methodsのニュアンスについて学びました。また、そのような単純な概念がより深い意味を持つ場合があることにも気付きました。
いつものように、完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-8[Githubに追加]を見つけることができます。