Java nije obavezna - orElse () vs orElseGet ()

1. Uvod

API za Neobvezno obično ima dvije metode koje mogu izazvati zabunu: ili drugo() i orElseGet ().

U ovom ćemo brzom vodiču pogledati razliku između njih dvoje i istražiti kada ih koristiti.

2. Potpisi

Krenimo prvo s osnovama gledajući njihove potpise:

javni T orElse (T ostalo) javni T orElseGet (dobavljač ostalo)

Jasno, ili drugo() uzima bilo koji parametar tipa T dok orElseGet () prihvaća funkcionalno sučelje tipa Dobavljač koji vraća objekt tipa T.

Sada, na temelju njihovih Javadocs-a:

  • ili drugo(): vraća vrijednost ako je prisutna, u suprotnom vraća drugo
  • orElseGet (): vraća vrijednost ako je prisutna, u suprotnom se poziva drugo i vratiti rezultat njegovog pozivanja

3. Razlike

Lako vas je malo zbuniti ovim pojednostavljenim definicijama, pa zato malo dublje i pogledajmo neke stvarne scenarije uporabe.

3.1. ili drugo()

Pod pretpostavkom da imamo svoj logger pravilno konfiguriran, krenimo s pisanjem jednostavnog dijela koda:

Ime niza = Neobavezno.of ("baeldung") .orElse (getRandomName ());

Primijeti da getRandomName () je metoda koja vraća slučajni slučaj Ime od Popisod imena:

javni String getRandomName () {LOG.info ("metoda getRandomName () - start"); Slučajni slučajni = novi Random (); int indeks = random.nextInt (5); LOG.info ("metoda getRandomName () - kraj"); vratiti imena.get (indeks); }

Tijekom izvršavanja našeg koda, u nastavku ćemo pronaći poruke ispisane na konzoli:

metoda getRandomName () - početak metode getRandomName () - kraj

Varijabla Ime održat će "Baeldung" na kraju izvršenja koda.

Pomoću nje možemo lako zaključiti da parametar od ili drugo() procjenjuje se čak i kada ima neprazno Neobvezno.

3.2. orElseGet ()

Pokušajmo sada napisati sličan kod koristeći orElseGet ():

Naziv niza = Neobvezno.of ("baeldung") .orElseGet (() -> getRandomName ());

Gornji kod se neće pozivati getRandomName () metoda.

Sjetite se (iz Javadoca) da je Supplier metoda prosljeđena kao argument izvršava se samo kada neobavezna vrijednost nije prisutna.

Koristeći orElseGet () jer će nam stoga naš slučaj uštedjeti neko vrijeme uključeno u računanje slučajnih rezultata Ime.

4. Mjerenje utjecaja na izvedbu

Sada, da bismo također razumjeli razlike u performansama, upotrijebimo JMH i pogledajte neke stvarne brojeve:

@Benchmark @BenchmarkMode (Mode.AverageTime) javni String iliElseBenchmark () {return Neobvezno.of ("baeldung"). OrElse (getRandomName ()); }

I orElseGet ():

@Benchmark @BenchmarkMode (Mode.AverageTime) javni niz iliElseGetBenchmark () {return Neobavezno.of ("baeldung"). OrElseGet (() -> getRandomName ()); }

Tijekom izvršavanja naših referentnih metoda dobivamo:

Benchmark Mode Cnt Rezultat Jedinice pogrešaka orElseBenchmark avgt 20 60934.425 ± 15115.599 ns / op orElseGetBenchmark avgt 20 3.798 ± 0.030 ns / op

Kao što vidimo, učinak na izvedbu mogao bi biti značajan čak i za tako jednostavan scenarij upotrebe.

Gore navedeni brojevi mogu se malo razlikovati, međutim, orElseGet () je očito nadmašio ili drugo() za naš konkretni primjer.

Nakon svega, ili drugo() uključuje izračunavanje getRandomName () metoda za svako trčanje.

5. Što je važno?

Osim aspekata izvedbe, drugi čimbenici koji vrijede uzeti u obzir uključuju:

  • Što ako bi metoda izvršila neku dodatnu logiku? Npr. izrada nekih DB umetaka ili ažuriranja
  • Čak i kad dodijelimo objekt ili drugo() parametar:
    Naziv niza = Neobvezno.of ("baeldung"). OrElse ("Ostalo")

    još uvijek stvaramo "Ostalo" objekt bez razloga

I zato nam je važno pažljivo donijeti odluku ili drugo() i orElseGet () ovisno o našim potrebama - prema zadanim postavkama ima smisla koristiti orElseGet () svaki put, osim ako je zadani objekt već izgrađen i dostupan mu je izravno.

6. Zaključak

U ovom smo članku naučili nijanse između Nije obavezno iliElse () i OrElseGet () metode. Također smo primijetili kako ponekad tako jednostavni pojmovi mogu imati dublje značenje.

Kao i uvijek, cjeloviti izvorni kod možete pronaći na Githubu.


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