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に追加]を見つけることができます。

前の投稿:Java Web Weekly 112
次の投稿:Java InputStreamからStringへ