Java Facultatif - orElse () vs orElseGet ()

1. Introduction

L'API de Optional a généralement deux méthodes qui peuvent prêter à confusion: orElse () et orElseGet () .

Dans ce rapide didacticiel, nous examinerons la différence entre ces deux éléments et déterminerons quand les utiliser.

2. Signatures

Commençons par les bases en regardant leurs signatures:

public T orElse(T other) public T orElseGet(Supplier other)

De toute évidence, OrElse () prend un paramètre quelconque d'un type T tandis que orElseGet () accepte une interface fonctionnelle de Type Fournisseur qui retourne un objet de type T .

Maintenant, sur la base de leurs Javadocs:

  • orElse () : retourne la valeur si présente, sinon retourne autre
  • orElseGet (): renvoie la valeur si elle est présente, sinon invoquez other et retournez le résultat de son appel

3. Différences

Il est facile d'être un peu confus par ces définitions simplifiées, alors creusons un peu plus loin et examinons certains scénarios d'utilisation réels.

3.1. ou sinon()

En supposant que notre enregistreur soit configuré correctement, commençons par écrire un simple morceau de code:

String name = Optional.of("baeldung") .orElse(getRandomName());

Notez que getRandomName () est une méthode qui renvoie un nom aléatoire à partir d'une liste de noms:

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); }

Lors de l'exécution de notre code, nous trouverons ci-dessous les messages imprimés dans la console:

getRandomName() method - start getRandomName() method - end

Le nom de la variable contiendra «baeldung» à la fin de l'exécution du code.

Avec lui, nous pouvons facilement en déduire que le paramètre de orElse () est évalué même avec un Optional non vide .

3.2. orElseGet ()

Maintenant, essayons d'écrire du code similaire en utilisant orElseGet () :

String name = Optional.of("baeldung") .orElseGet(() -> getRandomName());

Le code ci-dessus n'appellera pas la méthode getRandomName () .

N'oubliez pas (à partir du Javadoc) que la méthode S upplier passée comme argument n'est exécutée que lorsqu'une valeur facultative n'est pas présente.

Utiliser orElseGet () pour notre cas nous fera donc gagner du temps dans le calcul d'un nom aléatoire .

4. Mesure de l'impact sur les performances

Maintenant, pour comprendre également les différences de performances, utilisons JMH et voyons quelques chiffres réels:

@Benchmark @BenchmarkMode(Mode.AverageTime) public String orElseBenchmark() { return Optional.of("baeldung").orElse(getRandomName()); }

Et orElseGet () :

@Benchmark @BenchmarkMode(Mode.AverageTime) public String orElseGetBenchmark() { return Optional.of("baeldung").orElseGet(() -> getRandomName()); }

En exécutant nos méthodes de référence, nous obtenons:

Benchmark Mode Cnt Score Error Units orElseBenchmark avgt 20 60934.425 ± 15115.599 ns/op orElseGetBenchmark avgt 20 3.798 ± 0.030 ns/op

Comme nous pouvons le voir, l'impact sur les performances peut être substantiel, même pour un scénario d'utilisation aussi simple.

Les chiffres ci-dessus peuvent cependant varier légèrement, orElseGet () a clairement surpassé orElse () pour notre exemple particulier.

Après tout, orElse () implique le calcul de la méthode getRandomName () pour chaque exécution.

5. Qu'est-ce qui est important?

Outre les aspects liés à la performance, d'autres facteurs à considérer comprennent:

  • Et si la méthode exécutait une logique supplémentaire? Par exemple, faire des insertions de bases de données ou des mises à jour
  • Même lorsque nous affectons un objet au paramètre orElse () :
    String name = Optional.of("baeldung").orElse("Other")

    nous créons toujours un objet "Autre" sans raison

Et c'est pourquoi il est important pour nous de prendre une décision prudente entre orElse () et orElseGet () en fonction de nos besoins - par défaut, il est plus logique d'utiliser orElseGet () à chaque fois sauf si l'objet par défaut est déjà construit et accessible directement .

6. Conclusion

Dans cet article, nous avons appris les nuances entre les méthodes Optional orElse () et OrElseGet () . Nous avons également remarqué comment des concepts aussi simples peuvent parfois avoir une signification plus profonde.

Comme toujours, le code source complet peut être trouvé sur Github.