Java voliteľné - orElse () vs orElseGet ()

1. Úvod

API rozhrania Voliteľné má zvyčajne dve metódy, ktoré môžu spôsobiť zámenu: alebo iný() a orElseGet ().

V tomto rýchlom výučbe sa pozrieme na rozdiel medzi týmito dvoma a preskúmame, kedy ich použiť.

2. Podpisy

Najprv začnime od základov pohľadom na ich podpisy:

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

Jasne, alebo iný() vezme akýkoľvek parameter typu T keďže orElseGet () akceptuje funkčné rozhranie typu Dodávateľ ktorý vráti objekt typu T.

Teraz na základe ich Javadocs:

  • alebo iný(): vráti hodnotu, ak je k dispozícii, inak vráti iné
  • orElseGet (): vráti hodnotu, ak je k dispozícii, inak vyvolá iné a vráti výsledok jeho vyvolania

3. Rozdiely

Je ľahké byť trochu zmätení týmito zjednodušenými definíciami, takže poďme trochu hlbšie a pozrime sa na niektoré skutočné scenáre použitia.

3.1. alebo iný()

Za predpokladu, že máme náš záznamník nakonfigurovaný správne, začnime písaním jednoduchého kódu:

Názov reťazca = Optional.of ("baeldung") .orElse (getRandomName ());

Všimni si getRandomName () je metóda, ktorá vráti náhodný názov od a Zoznamz mená:

public String getRandomName () {LOG.info ("metóda getRandomName () - štart"); Random random = nový Random (); int index = random.nextInt (5); LOG.info ("metóda getRandomName () - koniec"); návrat names.get (index); }

Po vykonaní nášho kódu nájdeme nižšie správy vytlačené v konzole:

metóda getRandomName () - spustenie metódy getRandomName () - koniec

Premenná názov bude držať „Baeldung“ na konci vykonania kódu.

S ním môžeme ľahko odvodiť, že parameter alebo iný() sa vyhodnocuje, aj keď má neprázdny údaj Voliteľné.

3.2. orElseGet ()

Teraz skúsme napísať podobný kód pomocou orElseGet ():

Názov reťazca = Optional.of ("baeldung") .orElseGet (() -> getRandomName ());

Vyššie uvedený kód nebude vyvolať getRandomName () metóda.

Pamätajte (z Javadocu), že svroznášač metóda odovzdaná ako argument sa vykoná iba vtedy, keď voliteľné hodnota nie je prítomná.

Použitím orElseGet () v našom prípade nám teda ušetrí nejaký čas potrebný na výpočet náhodného výsledku názov.

4. Meranie dopadu na výkon

Teraz, aby sme pochopili aj rozdiely vo výkone, použijeme JMH a pozrieme si niektoré skutočné čísla:

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

A orElseGet ():

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

Pri vykonávaní našich referenčných metód získavame:

Benchmark Mode Cnt Score Error Units alebo ElseBenchmark priem. 20 60934,425 ± 15 115 599 ns / op alebo ElseGetBenchmark priem. 20 3,798 ± 0,030 ns / op

Ako vidíme, vplyv na výkon môže byť značný aj pre taký jednoduchý scenár prípadu použitia.

Vyššie uvedené čísla sa môžu mierne líšiť, orElseGet () jasne prekonala alebo iný() pre náš konkrétny príklad.

Po všetkom, alebo iný() zahŕňa výpočet getRandomName () metóda pre každý beh.

5. Čo je dôležité?

Okrem výkonnostných aspektov zahŕňajú aj ďalšie faktory, ktoré stoja za zváženie:

  • Čo ak by metóda vykonala nejakú ďalšiu logiku? Napr. robiť nejaké DB vložky alebo aktualizácie
  • Aj keď predmet priradíme alebo iný() parameter:
    Názov reťazca = Optional.of ("baeldung"). AleboElse ("Other")

    stále tvoríme „Iné“ objekt bezdôvodne

A preto je pre nás dôležité starostlivo sa rozhodnúť alebo iný() a orElseGet () podľa našich potrieb - v predvolenom nastavení má väčší zmysel použitie orElseGet () zakaždým, pokiaľ nie je predvolený objekt už zostavený a prístupný priamo.

6. Záver

V tomto článku sme sa dozvedeli nuansy medzi Voliteľné orElse () a OrElseGet () metódy. Tiež sme si všimli, ako môžu mať niekedy také jednoduché pojmy hlbší význam.

Kompletný zdrojový kód nájdete ako vždy na serveri Github.


$config[zx-auto] not found$config[zx-overlay] not found