Zoeken…


Invoering

Optional is een containerobject dat al dan niet een niet-nulwaarde kan bevatten. Als een waarde aanwezig is, isPresent() true en get() retourneert de waarde.

Aanvullende methoden die afhankelijk zijn van de aanwezigheid van de ingesloten waarde, zoals orElse() , die een standaardwaarde retourneert als waarde niet aanwezig is, en ifPresent() die een codeblok uitvoert als de waarde aanwezig is.

Syntaxis

  • Option.empty () // Maakt een lege optionele instantie.
  • Optioneel.van (waarde) // Retourneert een Optioneel met de opgegeven niet-nulwaarde. Een NullPointerException wordt gegenereerd als de doorgegeven waarde nul is.
  • Optioneel. VanNullable (waarde) // Retourneert een Optioneel met de opgegeven waarde die mogelijk null is.

Retourneer de standaardwaarde als Optioneel leeg is

Gebruik niet alleen Optional.get() want dat kan NoSuchElementException . De methoden Optional.orElse(T) en Optional.orElseGet(Supplier<? extends T>) bieden een manier om een standaardwaarde op te geven in het geval dat de optie Leeg is.

String value = "something";

return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
String value = null;

return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results

Het cruciale verschil tussen de orElse en orElseGet is dat de laatste alleen wordt geëvalueerd wanneer de Optioneel leeg is, terwijl het argument dat aan de vorige is gegeven wordt geëvalueerd, zelfs als de Optioneel niet leeg is. De orElse mag daarom alleen worden gebruikt voor constanten en nooit voor het leveren van waarde op basis van enige vorm van berekening.

Kaart

Gebruik de methode map() van Optional om te werken met waarden die mogelijk null zonder expliciete null voeren:

(Houd er rekening mee dat de bewerkingen map() en filter() onmiddellijk worden geëvalueerd, in tegenstelling tot hun Stream-tegenhangers die alleen worden geëvalueerd bij een terminalbewerking .)

Syntaxis:

public <U> Optional<U> map(Function<? super T,? extends U> mapper)

Code voorbeelden:

String value = null;

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
String value = "something";

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"

Omdat Option.map () een lege optie retourneert wanneer de toewijzingsfunctie null retourneert, kunt u verschillende map () -bewerkingen koppelen als een vorm van null-safe dereferencing. Dit wordt ook wel Null-safe chaining genoemd .

Overweeg het volgende voorbeeld:

String value = foo.getBar().getBaz().toString();

Elk van getBar , getBaz en toString kan mogelijk een NullPointerException .

Hier is een alternatieve manier om de waarde van toString() met Optional :

String value = Optional.ofNullable(foo)
                       .map(Foo::getBar)
                       .map(Bar::getBaz)
                       .map(Baz::toString)
                       .orElse("");

Dit retourneert een lege tekenreeks als een van de toewijzingsfuncties null heeft geretourneerd.

Hieronder is een ander voorbeeld, maar iets anders. De waarde wordt alleen afgedrukt als geen van de toewijzingsfuncties null heeft geretourneerd.

Optional.ofNullable(foo)
        .map(Foo::getBar)
        .map(Bar::getBaz)
        .map(Baz::toString)
        .ifPresent(System.out::println);

Gooi een uitzondering als er geen waarde is

Gebruik de methode orElseThrow() van Optional om de ingesloten waarde op te halen of een uitzondering te genereren, als deze niet is ingesteld. Dit is vergelijkbaar met het aanroepen van get() , behalve dat het willekeurige uitzonderingstypen toestaat. Voor de methode is een leverancier nodig die de uitzondering moet teruggeven.

In het eerste voorbeeld retourneert de methode eenvoudig de ingesloten waarde:

Optional optional = Optional.of("something");

return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string

In het tweede voorbeeld genereert de methode een uitzondering omdat er geen waarde is ingesteld:

Optional optional = Optional.empty();

return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException

U kunt ook de lambda-syntaxis gebruiken als een uitzondering met bericht moet worden weergegeven:

optional.orElseThrow(() -> new IllegalArgumentException("Illegal"));

Filter

filter() wordt gebruikt om aan te geven dat u de waarde alleen wilt als deze overeenkomt met uw predikaat.

Zie het als if (!somePredicate(x)) { x = null; } .

Code voorbeelden:

String value = null;
Optional.ofNullable(value) // nothing
        .filter(x -> x.equals("cool string"))// this is never run since value is null
        .isPresent(); // false
String value = "cool string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and passes
        .isPresent(); // true
String value = "hot string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and fails
        .isPresent(); // false

Optionele containers gebruiken voor primitieve nummertypen

OptionalDouble , OptionalInt en OptionalLong werken zoals Optional , maar zijn specifiek ontworpen om primitieve typen te verpakken:

OptionalInt presentInt = OptionalInt.of(value);
OptionalInt absentInt = OptionalInt.empty();

Omdat numerieke typen een waarde hebben, is er geen speciale afhandeling voor null. Lege containers kunnen worden gecontroleerd met:

presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.

Evenzo bestaan er steno's om waardebeheer te ondersteunen:

// Prints the value since it is provided on creation.
presentInt.ifPresent(System.out::println);

// Gives the other value as the original Optional is empty.
int finalValue = absentInt.orElseGet(this::otherValue);

// Will throw a NoSuchElementException.
int nonexistentValue = absentInt.getAsInt();

Voer code alleen uit als er een waarde aanwezig is

Optional<String> optionalWithValue = Optional.of("foo");
optionalWithValue.ifPresent(System.out::println);//Prints "foo".

Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);//Does nothing.

Geef een standaardwaarde op met behulp van een leverancier

De normale orElse methode heeft een Object , dus je kunt je afvragen waarom er een optie is om hier een Supplier te leveren (de orElseGet methode).

Overwegen:

String value = "something";
return Optional.ofNullable(value)
               .orElse(getValueThatIsHardToCalculate()); // returns "something"

Het zou nog steeds getValueThatIsHardToCalculate() aanroepen getValueThatIsHardToCalculate() ook al wordt het resultaat niet gebruikt omdat de optionele optie niet leeg is.

Om deze boete te voorkomen, levert u een leverancier:

String value = "something";
return Optional.ofNullable(value)
               .orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"

Op deze manier wordt getValueThatIsHardToCalculate() alleen aangeroepen als de Optional leeg is.

FlatMap

flatMap is vergelijkbaar met map . Het verschil wordt door de javadoc als volgt beschreven:

Deze methode is vergelijkbaar met map(Function) , maar de verstrekte mapper is er een waarvan het resultaat al een Optional , en indien aangeroepen, flatMap het niet in met een extra Optional .

Met andere woorden, wanneer u een methodeaanroep koppelt die een Optional retourneert, wordt met Optional.flatMap vermeden geneste Optionals .

Bijvoorbeeld, gegeven de volgende klassen:

public class Foo {
    Optional<Bar> getBar(){
        return Optional.of(new Bar());
    }
}

public class Bar {
}

Als u Optional.map , krijgt u een genest Optional ; dwz Optional<Optional<Bar>> .

Optional<Optional<Bar>> nestedOptionalBar =
    Optional.of(new Foo())
        .map(Foo::getBar);

Als u echter Optional.flatMap , krijgt u een eenvoudige Optional ; dwz Optional<Bar> .

Optional<Bar> optionalBar =
    Optional.of(new Foo())
        .flatMap(Foo::getBar);


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow