Guide til Java 8 Valgfritt

1. Oversikt

I denne opplæringen skal vi vise Valgfri klasse som ble introdusert i Java 8.

Hensikten med klassen er å tilby en type-nivå løsning for å representere valgfrie verdier i stedet for null referanser.

For å få en dypere forståelse av hvorfor vi bør bry oss om Valgfri klasse, ta en titt på den offisielle Oracle-artikkelen.

2. Opprette Valgfri Objekter

Det er flere måter å skape Valgfri gjenstander.

Å lage en tom Valgfri objekt, trenger vi bare å bruke dens tømme() statisk metode:

@Test offentlig ugyldig nårCreatesEmptyOptional_thenCorrect () {Valgfritt tom = Optional.empty (); assertFalse (tom.isPresent ()); }

Merk at vi brukte er tilstede() metode for å sjekke om det er en verdi inne i Valgfri gjenstand. En verdi er bare til stede hvis vi har skapt Valgfri med en ikke-null verdi. Vi ser på er tilstede() metode i neste avsnitt.

Vi kan også lage en Valgfri objekt med den statiske metoden av():

@Test public void givenNonNull_whenCreatesNonNullable_thenCorrect () {String name = "baeldung"; Valgfri opt = Optional.of (navn); assertTrue (opt.isPresent ()); }

Imidlertid ble argumentet overført til av() metoden kan ikke være null. Ellers får vi en NullPointerException:

@Test (forventet = NullPointerException.class) offentlig tomrom gittNull_whenThrowsErrorOnCreate_thenCorrect () {Strengnavn = null; Valgfritt. Av (navn); }

Men i tilfelle vi forventer noe null verdier, kan vi bruke ofNullable () metode:

@Test offentlig ugyldig givenNonNull_whenCreatesNullable_thenCorrect () {String name = "baeldung"; Valgfri opt = Optional.ofNullable (navn); assertTrue (opt.isPresent ()); }

Ved å gjøre dette, hvis vi passerer i a null referanse, det kaster ikke unntak, men returnerer heller et tomt Valgfri gjenstand:

@Test offentlig ugyldighet givenNull_whenCreatesNullable_thenCorrect () {Strengnavn = null; Valgfri opt = Optional.ofNullable (navn); assertFalse (opt.isPresent ()); }

3. Kontrollere verditilstedeværelse: er tilstede() og er tom()

Når vi har en Valgfri objekt returnert fra en metode eller opprettet av oss, kan vi sjekke om det er en verdi i den eller ikke med er tilstede() metode:

@Test offentlig ugyldighet gittOptional_whenIsPresentWorks_thenCorrect () {Valgfritt opt ​​= Optional.of ("Baeldung"); assertTrue (opt.isPresent ()); opt = Optional.ofNullable (null); assertFalse (opt.isPresent ()); }

Denne metoden returnerer ekte hvis den innpakkede verdien ikke er null.

Fra og med Java 11 kan vi gjøre det motsatte med er tom metode:

@Test offentlig ugyldighet givenAnEmptyOptional_thenIsEmptyBehavesAsExpected () {Valgfritt opt ​​= Optional.of ("Baeldung"); assertFalse (opt.isEmpty ()); opt = Optional.ofNullable (null); assertTrue (opt.isEmpty ()); }

4. Betinget handling med hvis tilstede()

De hvis tilstede() metoden gjør det mulig for oss å kjøre noen kode på den innpakkede verdien hvis den viser seg å værenull. Før Valgfri, ville vi gjort:

hvis (navn! = null) {System.out.println (name.length ()); }

Denne koden sjekker om navnet variabelen er null eller ikke før du fortsetter å utføre kode på den. Denne tilnærmingen er lang, og det er ikke det eneste problemet - det er også utsatt for feil.

Hva garanterer at etter at vi har skrevet ut variabelen, vil vi ikke bruke den igjen og da glemmer å utføre nullkontrollen?

Dette kan resultere i en NullPointerException ved kjøretid hvis en nullverdi finner veien inn i den koden. Når et program mislykkes på grunn av inputproblemer, er det ofte et resultat av dårlig programmeringspraksis.

Valgfri får oss til å håndtere nullverdier eksplisitt som en måte å håndheve god programmeringspraksis på.

La oss nå se på hvordan ovennevnte kode kan omformuleres i Java 8.

I typisk funksjonell programmeringsstil kan vi utføre en handling på et objekt som faktisk er til stede:

@Test public void givenOptional_whenIfPresentWorks_thenCorrect () {Optional opt = Optional.of ("baeldung"); opt.ifPresent (navn -> System.out.println (name.length ())); }

I eksemplet ovenfor bruker vi bare to linjer med kode for å erstatte de fem som fungerte i det første eksemplet: en linje for å pakke objektet inn i et Valgfri objektet og det neste for å utføre implisitt validering samt utføre koden.

5. Standardverdi med ellers()

De ellers() metoden brukes til å hente verdien innpakket i en Valgfri forekomst. Det tar en parameter, som fungerer som standardverdi. De ellers() metoden returnerer den innpakkede verdien hvis den er tilstede, og dens argument ellers:

@Test offentlig ugyldig nårOrElseWorks_thenCorrect () {String nullName = null; String name = Optional.ofNullable (nullName) .orElse ("john"); assertEquals ("john", navn); }

6. Standardverdi med orElseGet ()

De orElseGet () metoden ligner på ellers(). Imidlertid, i stedet for å ta en verdi å returnere hvis Valgfri verdien ikke er tilstede, det tar et leverandørfunksjonelt grensesnitt som påkalles og returnerer verdien av påkallelsen:

@Test offentlig ugyldig nårOrElseGetWorks_thenCorrect () {String nullName = null; String name = Optional.ofNullable (nullName) .orElseGet (() -> "john"); assertEquals ("john", navn); }

7. Forskjellen mellom ellers og orElseGet ()

For mange programmerere som er nye for Valgfri eller Java 8, forskjellen mellom ellers() og orElseGet () er ikke klar. Faktisk gir disse to metodene inntrykk av at de overlapper hverandre i funksjonalitet.

Imidlertid er det en subtil, men veldig viktig forskjell mellom de to som kan påvirke ytelsen til koden vår drastisk hvis ikke godt forstått.

La oss lage en metode som heter getMyDefault () i testklassen, som ikke tar noen argumenter og returnerer en standardverdi:

public String getMyDefault () {System.out.println ("Få standardverdi"); returner "Standardverdi"; }

La oss se to tester og observere bivirkningene for å fastslå begge hvor ellers() og orElseGet () overlapper hverandre og hvor de er forskjellige:

@Test offentlig ugyldig nårOrElseGetAndOrElseOverlap_thenCorrect () {Strengtekst = null; String defaultText = Optional.ofNullable (text) .orElseGet (this :: getMyDefault); assertEquals ("Standardverdi", defaultText); defaultText = Optional.ofNullable (text) .orElse (getMyDefault ()); assertEquals ("Standardverdi", defaultText); }

I eksemplet ovenfor pakker vi en nulltekst i en Valgfri objekt og prøv å få den innpakket verdien ved å bruke hver av de to tilnærmingene.

Bivirkningen er:

Få standardverdi ... Få standardverdi ...

De getMyDefault () metode kalles i hvert tilfelle. Det skjer slik at når den innpakkede verdien ikke er til stede, så begge deler ellers() og orElseGet () fungerer nøyaktig på samme måte.

La oss nå kjøre en ny test der verdien er tilstede, og ideelt sett bør ikke standardverdien opprettes:

@Test offentlig ugyldig nårOrElseGetAndOrElseDiffer_thenCorrect () {String text = "Text present"; System.out.println ("Bruke orElseGet:"); String defaultText = Optional.ofNullable (text) .orElseGet (this :: getMyDefault); assertEquals ("Text present", defaultText); System.out.println ("Bruke orElse:"); defaultText = Optional.ofNullable (text) .orElse (getMyDefault ()); assertEquals ("Text present", defaultText); }

I eksemplet ovenfor pakker vi ikke lenger inn en null verdi, og resten av koden forblir den samme.

La oss nå se på bivirkningen ved å kjøre denne koden:

Bruke orElseGet: Bruke orElse: Få standardverdi ...

Legg merke til at når du bruker orElseGet () for å hente innpakket verdi, getMyDefault () metoden blir ikke engang påkalt siden den inneholdte verdien er til stede.

Imidlertid når du bruker ellers(), enten den innpakkede verdien er tilstede eller ikke, opprettes standardobjektet. Så i dette tilfellet har vi nettopp opprettet et overflødig objekt som aldri blir brukt.

I dette enkle eksemplet er det ingen betydelige kostnader å opprette et standardobjekt, ettersom JVM vet hvordan de skal håndtere slike. Imidlertid når en metode som getMyDefault () må ringe en webservice eller til og med spørre om en database, blir kostnadene veldig åpenbare.

8. Unntak med orElseThrow ()

De orElseThrow () metoden følger av ellers() og orElseGet () og legger til en ny tilnærming for å håndtere en fraværende verdi.

I stedet for å returnere en standardverdi når den innpakkede verdien ikke er tilstede, kaster den et unntak:

@Test (forventet = IllegalArgumentException.class) offentlig ugyldig nårOrElseThrowWorks_thenCorrect () {String nullName = null; String name = Optional.ofNullable (nullName) .orElseThrow (IllegalArgumentException :: new); }

Metodereferanser i Java 8 kommer godt med her for å sende inn unntakskonstruktøren.

Java 10 introduserte en forenklet no-arg-versjon av orElseThrow () metode. I tilfelle en tom Valgfri det kaster en NoSuchElelementException:

@Test (forventet = NoSuchElementException.class) offentlig ugyldig nårNoArgOrElseThrowWorks_thenCorrect () {String nullName = null; String name = Optional.ofNullable (nullName) .orElseThrow (); }

9. Returnerende verdi med få()

Den siste tilnærmingen for å hente innpakket verdi er få() metode:

@Test offentlig ugyldighet gittOptional_whenGetsValue_thenCorrect () {Valgfritt opt ​​= Optional.of ("baeldung"); Strengnavn = opt.get (); assertEquals ("baeldung", navn); }

I motsetning til de tre foregående tilnærmingene, få() kan bare returnere en verdi hvis det innpakkede objektet ikke er null; Ellers kaster det et unntak av dette elementet:

@Test (forventet = NoSuchElementException.class) offentlig ugyldig givenOptionalWithNull_whenGetThrowsException_thenCorrect () {Valgfritt opt ​​= Optional.ofNullable (null); Strengnavn = opt.get (); }

Dette er den største feilen i få() metode. Ideelt sett, Valgfri burde hjelpe oss med å unngå slike uforutsette unntak. Derfor virker denne tilnærmingen mot målene for Valgfri og vil trolig bli avviklet i en fremtidig utgivelse.

Så det anbefales å bruke de andre variantene som gjør det mulig for oss å forberede oss på og eksplisitt håndtere null sak.

10. Betinget retur med filter()

Vi kan kjøre en inline test på vår innpakket verdi med filter metode. Det tar et predikat som argument og returnerer et Valgfri gjenstand. Hvis den innpakkede verdien består testingen av predikatet, vil Valgfri returneres som den er.

Imidlertid hvis predikatet returnerer falsk, så vil den returnere en tom Valgfri:

@Test offentlig ugyldig nårOptionalFilterWorks_thenCorrect () {Heltallår = 2016; Valgfritt år Valgfritt = Valgfritt. Av (år); boolsk is2016 = yearOptional.filter (y -> y == 2016) .isPresent (); assertTrue (is2016); boolsk is2017 = yearOptional.filter (y -> y == 2017) .isPresent (); assertFalse (is2017); }

De filter metoden brukes vanligvis på denne måten for å avvise innpakket verdier basert på en forhåndsdefinert regel. Vi kan bruke den til å avvise feil e-postformat eller passord som ikke er sterkt nok.

La oss se på et annet meningsfylt eksempel. Si at vi vil kjøpe et modem, og vi bryr oss bare om prisen.

Vi mottar push-varsler om modempriser fra et bestemt nettsted og lagrer disse i objekter:

offentlig klasse Modem {privat Dobbel pris; offentlig modem (dobbel pris) {this.price = pris; } // standard getters and setters}

Vi mater deretter disse objektene med noen kode hvis eneste formål er å sjekke om modemprisen er innenfor vårt budsjettområde.

La oss nå ta en titt på koden uten Valgfri:

public boolean priceIsInRange1 (Modem modem) {boolean isInRange = false; hvis (modem! = null && modem.getPrice ()! = null && (modem.getPrice ()> = 10 && modem.getPrice () <= 15)) {isInRange = true; } retur erInRange; }

Vær oppmerksom på hvor mye kode vi må skrive for å oppnå dette, spesielt i hvis tilstand. Den eneste delen av hvis tilstanden som er kritisk for applikasjonen er den siste prisklassen; resten av kontrollene er defensive:

@Test offentlig ugyldig nårFiltersWithoutOptional_thenCorrect () {assertTrue (priceIsInRange1 (nytt modem (10.0))); assertFalse (priceIsInRange1 (nytt modem (9.9))); assertFalse (priceIsInRange1 (nytt modem (null))); assertFalse (priceIsInRange1 (nytt modem (15.5))); assertFalse (priceIsInRange1 (null)); }

Bortsett fra det er det mulig å glemme nullkontrollene over en lang dag uten å få noen kompileringsfeil.

La oss nå se på en variant med Valgfritt # filter:

public boolean priceIsInRange2 (Modem modem2) {return Optional.ofNullable (modem2) .map (Modem :: getPrice) .filter (p -> p> = 10) .filter (p -> p <= 15) .isPresent (); }

De kart kall brukes ganske enkelt for å transformere en verdi til en annen verdi. Husk at denne operasjonen ikke endrer den opprinnelige verdien.

I vårt tilfelle skaffer vi oss et prisobjekt fra Modell klasse. Vi vil se på kart() metoden i detalj i neste avsnitt.

Først av alt, hvis en null objektet blir sendt til denne metoden, forventer vi ikke noe problem.

For det andre er den eneste logikken vi skriver i kroppen, akkurat det metodenavnet beskriver - prisklasse. Valgfri tar seg av resten:

@Test offentlig ugyldig nårFiltersWithOptional_thenCorrect () {assertTrue (priceIsInRange2 (nytt modem (10.0))); assertFalse (priceIsInRange2 (nytt modem (9.9))); assertFalse (priceIsInRange2 (nytt modem (null))); assertFalse (priceIsInRange2 (nytt modem (15.5))); assertFalse (priceIsInRange2 (null)); }

Den forrige tilnærmingen lover å sjekke prisklasse, men må gjøre mer enn det for å forsvare seg mot dens iboende skjøre. Derfor kan vi bruke filter metode for å erstatte unødvendig hvis uttalelser og avviser uønskede verdier.

11. Transforming Value With kart()

I forrige avsnitt så vi på hvordan vi kan avvise eller godta en verdi basert på et filter.

Vi kan bruke en lignende syntaks for å transformere Valgfri verdi med kart() metode:

@Test offentlig ugyldig gittOptional_whenMapWorks_thenCorrect () {List companyNames = Arrays.asList ("paypal", "oracle", "", "microsoft", "", "apple"); Valgfri listOptional = Optional.of (companyNames); int size = listOptional .map (List :: size) .orElse (0); assertEquals (6, størrelse); }

I dette eksemplet pakker vi en liste over strenger inne i en Valgfri motstand og bruk dens kart metode for å utføre en handling på listen som finnes. Handlingen vi utfører er å hente størrelsen på listen.

De kart metoden returnerer resultatet av beregningen pakket innvendig Valgfri. Vi må da kalle en passende metode på retur Valgfri for å hente verdien.

Legg merke til at filter metode utfører ganske enkelt en kontroll av verdien og returnerer a boolsk. De kart metoden tar imidlertid den eksisterende verdien, utfører en beregning ved hjelp av denne verdien, og returnerer resultatet av beregningen pakket inn i en Valgfri gjenstand:

@Test offentlig ugyldig gittOptional_whenMapWorks_thenCorrect2 () {String name = "baeldung"; Valgfritt navn Valgfritt = Valgfritt. Av (navn); int len ​​= nameOptional .map (String :: length) .orElse (0); assertEquals (8, len); }

Vi kan kjede kart og filter sammen for å gjøre noe kraftigere.

La oss anta at vi vil sjekke riktigheten av et passord som er skrevet inn av en bruker. Vi kan rense passordet ved hjelp av en kart transformasjon og sjekk korrektheten ved hjelp av en filter:

@Test offentlig ugyldig gittOptional_whenMapWorksWithFilter_thenCorrect () {String password = "password"; Valgfri passOpt = Optional.of (passord); boolsk correctPassword = passOpt.filter (pass -> pass.equals ("passord")). isPresent (); assertFalse (correctPassword); correctPassword = passOpt .map (String :: trim) .filter (pass -> pass.equals ("password")) .isPresent (); assertTrue (correctPassword); }

Som vi kan se, uten å først rengjøre inngangen, blir den filtrert ut - likevel kan brukere ta for gitt at ledende og etterfølgende mellomrom alle utgjør inngang. Så vi forvandler et skittent passord til et rent med en kart før du filtrerer ut feil.

12. Transforming Value With flatMap ()

Akkurat som kart() metoden, har vi også flatMap () metode som et alternativ for å transformere verdier. Forskjellen er at kart transformerer bare verdier når de pakkes ut mens flatMap tar en innpakket verdi og pakker den ut før den transformeres.

Tidligere opprettet vi enkle String og Heltall gjenstander for innpakning i en Valgfri forekomst. Imidlertid vil vi ofte motta disse objektene fra en tilgang til et komplekst objekt.

For å få et klarere bilde av forskjellen, la oss ta en titt på a Person objekt som tar en persons detaljer som navn, alder og passord:

offentlig klasse Person {private Strengnavn; privat alder; privat strengpassord; public Optional getName () {return Optional.ofNullable (name); } offentlig Valgfri getAge () {retur Optional.ofNullable (alder); } offentlig Valgfri getPassword () {retur Optional.ofNullable (passord); } // normale konstruktører og settere}

Vi vil normalt lage et slikt objekt og pakke det inn i et Valgfri objekt akkurat som vi gjorde med String.

Alternativt kan den returneres til oss ved en annen metodeanrop:

Personperson = ny person ("john", 26); Valgfri personOptional = Optional.of (person);

Legg merke til nå at når vi pakker inn en Person objekt, vil den inneholde nestet Valgfri forekomster:

@Test offentlig ugyldig gittOptional_whenFlatMapWorks_thenCorrect2 () {Person person = new Person ("john", 26); Valgfri personOptional = Optional.of (person); Valgfri nameOptionalWrapper = personOptional.map (Person :: getName); Valgfritt navnOptional = nameOptionalWrapper.orElseThrow (IllegalArgumentException :: new); String name1 = nameOptional.orElse (""); assertEquals ("john", name1); String name = personOptional .flatMap (Person :: getName) .orElse (""); assertEquals ("john", navn); }

Her prøver vi å hente navnattributtet til Person motsette seg for å utføre en påstand.

Legg merke til hvordan vi oppnår dette med kart() metode i tredje uttalelse, og legg merke til hvordan vi gjør det samme med flatMap () metode etterpå.

De Person :: getName metoden referanse er lik den Streng :: trim samtale vi hadde i forrige avsnitt for å rydde opp et passord.

Den eneste forskjellen er at getName () returnerer en Valgfri snarere enn en streng som gjorde listverk() operasjon. Dette, kombinert med det faktum at en kart transformasjon bryter resultatet inn i en Valgfri objekt, fører til en nestet Valgfri.

Mens du bruker kart() metoden, derfor må vi legge til et ekstra anrop for å hente verdien før vi bruker den transformerte verdien. På denne måten, Valgfri innpakningen vil bli fjernet. Denne operasjonen utføres implisitt når den brukes flatMap.

13. Kjetting Valgfris i Java 8

Noen ganger kan det hende vi trenger å få den første som ikke er tom Valgfri objekt fra en rekke Valgfris. I slike tilfeller vil det være veldig praktisk å bruke en metode som orElseOptional (). Dessverre støttes ikke slik operasjon direkte i Java 8.

La oss først introdusere noen metoder som vi skal bruke gjennom hele denne delen:

private Optional getEmpty () {return Optional.empty (); } privat Valgfri getHello () {retur Optional.of ("hei"); } privat Valgfri getBye () {retur Optional.of ("farvel"); } privat Valgfritt createOptional (String input) {if (input == null || "" .equals (input) || "tom" .equals (input)) {return Optional.empty (); } returner Optional.of (input); }

For å kjede flere Valgfri objekter og få den første som ikke er tom i Java 8, kan vi bruke Strøm API:

@Test offentlig ugyldighet givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturned () {Valgfritt funnet = Stream.of (getEmpty (), getHello (), getBye ()) .filter (Valgfritt :: isPresent) .map (Valgfritt :: get) .findFirst (); assertEquals (getHello (), funnet); }

Ulempen med denne tilnærmingen er at alle våre metoder utføres alltid, uavhengig av hvor en ikke-tom Valgfri vises i Strøm.

Hvis vi lat evaluere metodene vi har gitt til Stream.of (), må vi bruke metoden referanse og Leverandør grensesnitt:

@Test offentlig ugyldighet givenThreeOptionals_whenChaining_thenFirstNonEmptyIsReturnedAndRestNotEvaluated () {Valgfritt funnet = Stream.<>> av (dette :: getEmpty, dette :: getHello, dette :: getBye) .map (Leverandør :: get) .filter (Valgfritt :: isPresent) .map (Valgfritt :: get) .findFirst (); assertEquals (getHello (), funnet); }

I tilfelle vi trenger å bruke metoder som tar argumenter, må vi ty til lambdauttrykk:

@Test offentlig tomrom gittTwoOptionalsReturnedByOneArgMethod_whenChaining_thenFirstNonEmptyIsReturned () {Valgfritt funnet = Stream.<>> av (() -> createOptional ("tom"), () -> createOptional ("hallo")). kart (Leverandør :: get) .filter (Valgfritt :: isPresent) .map (Valgfritt :: get). findFirst (); assertEquals (createOptional ("hallo"), funnet); }

Ofte vil vi returnere en standardverdi i tilfelle alle lenker Valgfris er tomme. Vi kan gjøre det bare ved å legge til en samtale til ellers() eller orElseGet ():

@Test offentlig ugyldighet givenTwoEmptyOptionals_whenChaining_thenDefaultIsReturned () {Streng funnet = Stream.<>> av (() -> createOptional ("tom"), () -> createOptional ("tom")) .map (Leverandør :: get) .filter (Valgfritt :: isPresent) .map (Valgfritt :: get). findFirst () .orElseGet (() -> "standard"); assertEquals ("standard", funnet); }

14. JDK 9 Valgfri API

Utgivelsen av Java 9 la enda flere nye metoder til Valgfri API:

  • eller() metode for å tilby en leverandør som skaper et alternativ Valgfri
  • ifPresentOrElse () metode som gjør det mulig å utføre en handling hvis Valgfri er til stede eller en annen handling hvis ikke
  • strøm() metode for konvertering av en Valgfri til en Strøm

Her er den komplette artikkelen for videre lesing.

15. Misbruk av Valgfris

Til slutt, la oss se en fristende, men farlig måte å bruke Valgfris: passerer en Valgfri parameter til en metode.

Tenk deg at vi har en liste over Person og vi vil ha en metode for å søke gjennom den listen etter personer med et gitt navn. Vi vil også at metoden skal matche oppføringer med minst en viss alder, hvis den er spesifisert.

Med denne parameteren som valgfri, kommer vi med denne metoden:

offentlig statisk liste søk (liste personer, strengnavn, valgfri alder) {// Null sjekker for personer og navn returnerer personer.strøm () .filter (p -> p.getnavn (). er lik (navn)) .filter (p -> p.getAge (). get ()> = age.orElse (0)) .collect (Collectors.toList ()); }

Så slipper vi metoden vår, og en annen utvikler prøver å bruke den:

someObject.search (folk, "Peter", null);

Nå utfører utvikleren koden sin og får en NullPointerException.Der er vi nødt til å sjekke den valgfrie parameteren vår, som beseirer vårt opprinnelige formål med å ønske å unngå denne typen situasjoner.

Her er noen muligheter vi kunne ha gjort for å håndtere det bedre:

offentlig statisk liste søk (liste personer, strengnavn, heltall) {// Null kontroller for personer og navn endelig Heltall ageFilter = alder! = null? alder: 0; returnere people.stream () .filter (p -> p.getName (). er lik (navn)) .filter (p -> p.getAge (). get ()> = ageFilter) .collect (Collectors.toList () ); }

Der er parameteren fremdeles valgfri, men vi håndterer den bare i en sjekk.

En annen mulighet ville ha vært å lage to overbelastede metoder:

offentlig statisk Listesøk (List folk, String name) {return doSearch (people, name, 0); } offentlig statisk Listesøk (Liste personer, String navn, int alder) {return doSearch (personer, navn, alder); } privat statisk liste doSearch (liste personer, strengnavn, int alder) {// Null sjekker for personer og navn returnerer people.stream () .filter (p -> p.getName (). tilsvarer (navn)) .filter ( p -> p.getAge (). get (). intValue ()> = alder) .collect (Collectors.toList ()); }

På den måten tilbyr vi en klar API med to metoder som gjør forskjellige ting (selv om de deler implementeringen).

Så det er løsninger som skal unngås Valgfris som metodeparametere. Hensikten med Java når du slipper Valgfri skulle bruke den som returtype, og indikerer dermed at en metode kan returnere en tom verdi. Faktisk, bruken av å bruke Valgfri som en metode parameter til og med motet av noen kode inspektører.

16. Valgfri og serialisering

Som diskutert ovenfor, Valgfri er ment å brukes som returtype. Det anbefales ikke å prøve å bruke den som felttype.

I tillegg ved hjelp av Valgfri i en serie som kan sorteres, vil resultere i en NotSerializableException. Vår artikkel Java Valgfri som Returtype adresserer videre problemene med serialisering.

Og i bruk Valgfri Med Jackson forklarer vi hva som skjer når Valgfri felt serialiseres, sammen med noen få løsninger for å oppnå de ønskede resultatene.

17. Konklusjon

I denne artikkelen dekket vi de fleste viktige funksjonene i Java 8 Valgfri klasse.

Vi undersøkte kort noen grunner til at vi valgte å bruke Valgfri i stedet for eksplisitt nullkontroll og inndatavalidering.

Vi lærte også å få verdien av en Valgfrieller en standard hvis den er tom, med få(), ellers() og orElseGet () metoder (og så den viktige forskjellen mellom de to siste).

Så så vi hvordan vi kunne transformere eller filtrere Valgfris med map (), flatMap () og filter(). Vi diskuterte hva flytende APIValgfri tilbyr, ettersom det lar oss enkelt kjede de forskjellige metodene.

Til slutt så vi hvorfor bruk Valgfris som metodeparametere er en dårlig ide og hvordan man kan unngå det.

Kildekoden for alle eksemplene i artikkelen er tilgjengelig på GitHub.


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