Java valgfri - orElse () vs orElseGet ()

1. Introduktion

API af Valgfri har typisk to metoder, der kan forårsage forvirring: ellers() og orElseGet ().

I denne hurtige vejledning ser vi på forskellen mellem disse to og undersøger, hvornår de skal bruges.

2. Underskrifter

Lad os først starte med det grundlæggende ved at se på deres underskrifter:

public T orElse (T other) public T orElseGet (Other leverandør)

Klart, ellers() tager enhver parameter af en type T der henviser til orElseGet () accepterer en funktionel grænseflade af typen Leverandør der returnerer et objekt af typen T.

Nu, baseret på deres Javadocs:

  • ellers(): returnerer værdien, hvis den er til stede, ellers returneres Andet
  • orElseGet (): returnerer værdien, hvis den er til stede, ellers påberåbes Andet og returnere resultatet af dets påberåbelse

3. Forskelle

Det er let at være lidt forvirret af disse forenklede definitioner, så lad os grave lidt dybere og se på nogle faktiske brugsscenarier.

3.1. ellers()

Forudsat at vi har vores logger konfigureret korrekt, lad os starte med at skrive et simpelt stykke kode:

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

Læg mærke til det getRandomName () er en metode, der returnerer en tilfældig navn fra en Listeaf navne:

offentlig streng getRandomName () {LOG.info ("getRandomName () metode - start"); Tilfældig tilfældig = ny tilfældig (); int-indeks = random.nextInt (5); LOG.info ("getRandomName () metode - slut"); return names.get (indeks); }

Når vi udfører vores kode, finder vi nedenstående meddelelser, der er trykt i konsollen:

getRandomName () metode - start getRandomName () metode - slut

Variablen navn holder “Baeldung” i slutningen af ​​kodeudførelsen.

Med det kan vi let udlede, at parameter for ellers() evalueres, selv når du har en ikke-tom Valgfri.

3.2. orElseGet ()

Lad os nu prøve at skrive lignende kode ved hjælp af orElseGet ():

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

Ovenstående kode påberåber sig ikke getRandomName () metode.

Husk (fra Javadoc), at Sopplier metode bestået som et argument udføres kun når en valgfri værdi er ikke til stede.

Ved brug af orElseGet () for vores sag vil derfor spare os noget tid til at beregne et tilfældigt navn.

4. Måling af ydeevneeffekt

Nu, for også at forstå forskellene i ydeevne, lad os bruge JMH og se nogle faktiske tal:

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

Og orElseGet ():

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

Mens vi udfører vores benchmarkmetoder får vi:

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

Som vi kan se, kan ydeevneeffekten være betydelig, selv for et så simpelt brugsscenarie.

Tallene ovenfor kan variere lidt, dog orElseGet () har klart overgået ellers() for vores særlige eksempel.

Trods alt, ellers() involverer beregning af getRandomName () metode for hver kørsel.

5. Hvad er vigtigt?

Bortset fra præstationsaspekterne involverer andre værdifulde faktorer:

  • Hvad hvis metoden ville udføre yderligere logik? F.eks. lave nogle DB-indsatser eller opdateringer
  • Selv når vi tildeler et objekt til ellers() parameter:
    String name = Optional.of ("baeldung"). OrElse ("Other")

    vi skaber stadig "Andet" genstand uden grund

Og det er derfor det er vigtigt for os at tage en omhyggelig beslutning blandt ellers() og orElseGet () afhængigt af vores behov - som standard giver det mere mening at bruge orElseGet () hver gang, medmindre standardobjektet allerede er konstrueret og tilgængeligt direkte.

6. Konklusion

I denne artikel har vi lært nuancerne imellem Valgfri eller Else () og OrElseGet () metoder. Vi bemærkede også, hvordan sådanne enkle begreber undertiden kan have en dybere betydning.

Som altid kan den komplette kildekode findes på Github.


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