Java-Null-Safe-Streams aus Sammlungen

1. Überblick

In diesem Lernprogramm erfahren Sie, wie Sie nullsichere Streams aus Java-Sammlungen erstellen.

Um mit diesem Material vertraut zu werden, sind zunächst einige Kenntnisse der Methodenreferenzen, Lambda-Ausdrücke, Optional und Stream-API von Java 8 erforderlich.

Wenn Sie mit einem dieser Themen nicht vertraut sind, schauen Sie sich zuerst unsere vorherigen Artikel an:

2. Maven-Abhängigkeit

Bevor wir beginnen, gibt es eine Maven-Abhängigkeit, die wir für bestimmte Szenarien brauchen werden:

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

Die Bibliothek commons-collection4 kann von Maven Central heruntergeladen werden.

3. Streams aus Sammlungen erstellen

Der grundlegende Ansatz zum Erstellen einer Stream aus einem beliebigen Collection -Typ besteht darin, die stream () - oder parallelStream () -Methoden der Collection abhängig von aufzurufen die Art des Streams, der erforderlich ist:

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

Unsere Sammlung wird höchstwahrscheinlich irgendwann eine externe Quelle haben. Am Ende wird wahrscheinlich eine Methode ähnlich der unten stehenden Methode zum Erstellen von Streams aus Sammlungen vorhanden sein:

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

Dies kann zu Problemen führen. Wenn die bereitgestellte Sammlung auf eine null -Referenz verweist, wirft der Code zur Laufzeit eine NullPointerException aus.

Im folgenden Abschnitt wird beschrieben, wie wir uns dagegen schützen können.

4. Erstellte Collection-Streams zu Null-Safe machen

4.1. Schecks hinzufügen, um Null Dereferences zu verhindern

Um unbeabsichtigte Ausnahmen für null pointer zu verhindern, können wir optional Prüfungen hinzufügen, um null reference ** beim Erstellen von Streams aus Sammlungen zu verhindern

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

Diese Methode hat jedoch einige Probleme.

Erstens behindert der null check die Geschäftslogik, wodurch die Lesbarkeit des Programms insgesamt verringert wird.

Zweitens wird die Verwendung von null zur Darstellung des Fehlens eines Werts nach Java SE 8 als falscher Ansatz betrachtet: Es gibt einen besseren Weg, um das Fehlen und Vorhandensein eines Wertes zu modellieren.

Es ist wichtig zu wissen, dass eine leere Collection nicht mit einer null Collection identisch ist. Während der erste Hinweis darauf hinweist, dass für unsere Abfrage keine Ergebnisse oder Elemente angezeigt werden, weist der zweite darauf hin, dass während des Prozesses eine Art Fehler aufgetreten ist.

4.2. Verwenden Sie die emptyIfNull -Methode aus der CollectionUtils Library

Wir können Apache Commons https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html ]verwenden, um sicherzustellen, dass unser Stream null safe ist. Diese Bibliothek stellt eine emptyIfNull -Methode bereit, die eine unveränderliche leere Auflistung zurückgibt, wenn eine null -Auflistung als Argument angegeben wird, oder die Auflistung selbst:

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

Dies ist eine sehr einfache Strategie. Dies hängt jedoch von einer externen Bibliothek ab. Wenn eine Softwareentwicklungsrichtlinie die Verwendung einer solchen Bibliothek einschränkt, wird diese Lösung null und nichtig erklärt.

4.3. Verwenden Sie Java 8s Optional

Https://www.baeldung.com/java-optional[ Optional ]von Java SE 8 ist ein Container mit einem einzigen Wert, der entweder einen Wert enthält oder nicht. Wenn ein Wert fehlt, wird der Optional -Container als leer bezeichnet.

Die Verwendung von Optional kann als die beste Gesamtstrategie zum Erstellen einer nullsicheren Auflistung aus einem Stream betrachtet werden.

Mal sehen, wie wir es benutzen können, gefolgt von einer kurzen Diskussion unten:

public Stream<String> collectionToStream(Collection<String> collection) {
    return Optional.ofNullable(collection)
      .map(Collection::stream)
      .orElseGet(Stream::empty);
}
  • Optional.ofNullable (collection) erstellt ein Optional -Objekt aus

die übergebene Sammlung. Ein leeres Optional -Objekt wird erstellt, wenn das Sammlung ist null. map (Collection :: stream) ** extrahiert den im. enthaltenen Wert

Optional Objekt als Argument für die map -Methode ( Collection.stream () ) orElseGet (Stream :: empty) ** gibt den Fallback-Wert im Ereignis zurück

dass das Optional -Objekt leer ist, d. h. die übergebene Sammlung ist null .

Daher schützen wir unseren Code proaktiv vor unbeabsichtigten null -Pointer-Ausnahmen.

4.4. Stream OfNullable von Java 9 verwenden

Untersuchen unseres vorherigen ternären Beispiels in Abschnitt 4.1. und wenn man bedenkt, dass einige Elemente null anstelle der Collection sein könnten, steht uns die ofNullable -Methode in der Stream -Klasse zur Verfügung.

Wir können das obige Beispiel umwandeln in:

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

5. Fazit

In diesem Artikel haben wir kurz beschrieben, wie Sie einen Stream aus einer gegebenen Sammlung erstellen. Anschließend haben wir die drei wichtigsten Strategien untersucht, um sicherzustellen, dass der erstellte Stream nullsicher ist, wenn er aus einer Sammlung erstellt wird.

Abschließend haben wir auf die Schwäche der jeweiligen Strategie hingewiesen, sofern dies relevant ist.

Wie üblich ist der vollständige Quellcode, der dem Artikel beiliegt, verfügbar: über GitHub .