Java >> Java tutorial >  >> Java

Java Null-Safe Streams fra samlinger

1. Oversigt

I denne øvelse vil vi se, hvordan du opretter nul-sikre streams fra Java-samlinger.

Til at starte med, en vis fortrolighed med Java 8's Method References, Lambda Expressions, Valgfri og Stream API er påkrævet for fuldt ud at forstå dette materiale.

Hvis du ikke er bekendt med nogen af ​​disse emner, så tag først et kig på vores tidligere artikler:Nye funktioner i Java 8, Guide til valgfri Java 8 og Introduktion til Java 8-streams.

2. Maven Dependency

Før vi begynder, er der én Maven-afhængighed, som vi får brug for til visse scenarier:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.2</version>
</dependency>

commons-collections4 bibliotek kan downloades fra Maven Central.

3. Oprettelse af streams fra samlinger

Den grundlæggende tilgang til at skabe en Strøm fra enhver type Samling er at kalde stream() eller parallelStream() metoder på samlingen afhængigt af den type stream, der kræves:

Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();

Vores samling vil højst sandsynligt have en ekstern kilde på et tidspunkt, vi ender sandsynligvis med en metode svarende til nedenstående, når vi opretter streams fra samlinger:

public Stream<String> collectionAsStream(Collection<String> collection) {
    return collection.stream();
}

Dette kan give nogle problemer. Når den angivne samling peger på en nul reference, vil koden kaste en NullPointerException ved kørsel.

Det følgende afsnit omhandler, hvordan vi kan beskytte os mod dette.

4. Gør oprettede samlingsstreams null-sikre

4.1. Tilføj kontrol for at forhindre Nul Henvisninger

For at forhindre utilsigtet null pointer undtagelser, vi kan vælge at tilføje kontrol for at forhindre null referencer når du opretter streams fra samlinger:

Stream<String> collectionAsStream(Collection<String> collection) {
    return collection == null 
      ? Stream.empty() 
      : collection.stream();
}

Denne metode har dog et par problemer.

Først null check kommer i vejen for forretningslogikken, der forringer programmets overordnede læsbarhed.

For det andet brugen af ​​null at repræsentere fraværet af en værdi betragtes som en forkert tilgang post-Java SE 8:Der er en bedre måde at modellere fraværet og tilstedeværelsen af ​​en værdi på.

Det er vigtigt at huske på, at der er en tom samling er ikke det samme som en nul Samling . Mens den første indikerer, at vores forespørgsel ikke har resultater eller elementer at vise, antyder den anden, at der lige er sket en slags fejl under processen.

4.2. Brug emptyIfNull Metode fra CollectionUtils Bibliotek

Vi kan vælge at bruge Apache Commons' CollectionUtils bibliotek for at sikre, at vores stream er nul sikker. Dette bibliotek giver en emptyIfNull metode, som returnerer en uforanderlig tom samling givet en nul samling som argument, eller selve samlingen i øvrigt:

public Stream<String> collectionAsStream(Collection<String> collection) {
    return emptyIfNull(collection).stream();
}

Dette er en meget enkel strategi at vedtage. Det afhænger dog af et eksternt bibliotek. Hvis en softwareudviklingspolitik begrænser brugen af ​​et sådant bibliotek, bliver denne løsning gengivet nul og ugyldig.

4.3. Brug Java 8's Valgfri

Java SE 8's Valgfri er en enkeltværdibeholder, der enten indeholder en værdi eller ikke gør. Hvor en værdi mangler, er Valgfri beholderen siges at være tom.

Brug Valgfrit kan uden tvivl betragtes som den bedste overordnede strategi til at skabe en nul-sikker samling fra en strøm.

Lad os se, hvordan vi kan bruge det efterfulgt af en hurtig diskussion nedenfor:

public Stream<String> collectionToStream(Collection<String> collection) {
    return Optional.ofNullable(collection)
      .map(Collection::stream)
      .orElseGet(Stream::empty);
}
  • Optional.ofNullable(collection) opretter en Valgfri genstand fra den indleverede samling. En tom Valgfri objekt oprettes, hvis samlingen er null.
  • kort(Collection::stream) udtrækker værdien indeholdt i Valgfri objekt som et argument til kortet metode (Collection.stream() )
  • orElseGet(Stream::empty) returnerer reserveværdien i tilfælde af, at Valgfri objektet er tomt, dvs. den indsendte samling er null .

Som et resultat beskytter vi proaktivt vores kode mod utilsigtet null pointer undtagelser.

4.4. Brug Java 9's Stream OfNullable

Undersøgelse af vores tidligere ternære eksempel i afsnit 4.1. og overvejer muligheden for, at nogle elementer kunne være null i stedet for Samlingen , har vi til vores rådighed det afNullable metode i Strømmen klasse.

Vi kan omdanne ovenstående eksempel til:

Stream<String> collectionAsStream(Collection<String> collection) {  
  return collection.stream().flatMap(s -> Stream.ofNullable(s));
}

5. Konklusion

I denne artikel har vi kort gennemgået, hvordan man opretter en stream fra en given samling. Vi fortsatte derefter med at udforske de tre nøglestrategier for at sikre, at den oprettede stream er nul-sikker, når den oprettes fra en samling.

Til sidst påpegede vi svagheden ved at bruge hver strategi, hvor det er relevant.

Som sædvanlig er den fulde kildekode, der følger med artiklen, tilgængelig på GitHub.


Java tag