Nullsichere Sammlung als Stream in Java 8

Lesezeit: 4 Minuten

Benutzer-Avatar
Gondy

Ich suche nach einer Methode, die einen Sammlungsstrom erstellen kann, aber null sicher ist. Wenn die Sammlung null ist, wird ein leerer Stream zurückgegeben. So was:

Utils.nullSafeStream(collection).filter(...);

Ich habe meine eigene Methode erstellt:

public static <T> Stream<T> nullSafeStream(Collection<T> collection) {
    if (collection == null) {
        return Stream.empty();
    }
    return collection.stream();
}

Aber ich bin neugierig, ob es so etwas im Standard-JDK gibt?

  • Sie sollten versuchen, dies zu vermeiden null Sammlung an erster Stelle. Die beste Vorgehensweise besteht darin, stattdessen lieber eine leere Sammlung zu verwenden.

    – Didier L

    11. Januar 2017 um 12:16 Uhr

  • Ja, ich stimme zu, aber wenn Sie auf die Bibliothek einer anderen Person angewiesen sind, haben Sie keine Wahl.

    – Gondi

    20. März 2017 um 18:31 Uhr

  • In diesem Fall könnten Sie die Sammlung, die Sie von dieser Bibliothek erhalten, einfach durch eine leere ersetzen, wenn sie zurückkehrt null. Ein bisschen wie in gregs Lösung.

    – Didier L

    22. März 2017 um 21:48 Uhr

Benutzer-Avatar
Eran

Du könntest benutzen Optional :

Optional.ofNullable(collection).orElse(Collections.emptySet()).stream()...

Ich entschied mich Collections.emptySet() willkürlich als Standardwert für den Fall collection ist Null. Dies führt zu der stream() Methodenaufruf, der eine leere erzeugt Stream wenn collection ist Null.

Beispiel :

Collection<Integer> collection = Arrays.asList (1,2,3);
System.out.println (Optional.ofNullable(collection).orElse(Collections.emptySet()).stream().count ());
collection = null;
System.out.println (Optional.ofNullable(collection).orElse(Collections.emptySet()).stream().count ());

Ausgabe:

3
0

Alternativ können Sie, wie von marstran vorgeschlagen, Folgendes verwenden:

Optional.ofNullable(collection).map(Collection::stream).orElse(Stream.empty ())...

  • Optional.ofNullable(collection).map(Collection::stream).orElse(Stream.empty()); ist eine mögliche gleichwertige Lösung, bei der Sie sich nicht entscheiden müssen Collections.emptySet().

    – Marsran

    11. Januar 2017 um 11:59 Uhr

  • Wie von @StuartMarks als erwähnt Nutzung, abstruse Nutzung und Missbrauch: Regel Nr. 4: Es ist im Allgemeinen eine schlechte Idee, eine zu erstellen Optional für den alleinigen Zweck, Methoden daraus zu verketten, um einen Wert zu erhalten.

    – Didier L

    11. Januar 2017 um 13:04 Uhr


  • @DidierL Ich kann mir diesen YouTube-Clip gerade nicht ansehen, aber mein erster Eindruck ist, dass ich im Allgemeinen nicht zustimme. Ich werde es später heute überprüfen. Der Fall, den wir hier haben, sieht ziemlich sauber aus collection != null ? collections.stream() : Stream.empty(); obwohl.

    – Marsran

    11. Januar 2017 um 13:37 Uhr


  • @marstran Der Punkt von Stuart Marks ist, dass es im Allgemeinen besser lesbar ist, kein optionales zu verwenden (außer der Tatsache, dass es etwas Boxen und Outboxing vermeidet). Dies bleibt natürlich eine Richtlinie.

    – Didier L

    11. Januar 2017 um 16:50 Uhr

  • Ich denke es kommt auf die Kette an. Wenn es sich um eine Kette handelt, die nur auf Null für die übergebene Referenz prüft, ist dies wahrscheinlich zu viel des Guten. Das Verketten mit Optional ist jedoch nützlich, wenn Sie zwei oder mehr Ebenen des Objektdiagramms nach unten tauchen und bei jedem Schritt auf Null prüfen, um einen Wert zu erhalten. An diesem Punkt quetschen Sie eine Reihe verschachtelter bedingter Anweisungen. An diesem Punkt ist meiner Meinung nach die optionale Verkettung sauberer und einfacher zu lesen.

    – 8bitjunkie

    20. März 2018 um 12:24 Uhr


Benutzer-Avatar
Greg

Sie können die Funktion org.apache.commons.collections4.CollectionUtils::emptyIfNull verwenden:

import static org.apache.commons.collections4.CollectionUtils.emptyIfNull;
      
emptyIfNull(list).stream()
                 .filter(...);

  • Ich mag diese Lösung eigentlich, weil sie sehr einfach ist. Eine externe Bibliothek ist jedoch erforderlich, aber in der Welt von Maven und Gradle ist dies kein Problem. Ich weiß, dass ich nach JDK8 gefragt habe, aber anscheinend ist nichts so Einfaches da.

    – Gondi

    28. März 2017 um 13:19 Uhr


  • Kann nicht verwendet werden orElse oder orElseThrow damit, aber Optional.ofNullable() bietet beide Methoden an.

    – Farrukh Chishti

    26. Februar 2019 um 7:14 Uhr

  • Hängt von der Anforderung ab. Aber wenn Sie eigentlich nur eine emptyCollection in Ihrem .orElse()-Aufruf wollen, finde ich das viel schöner zu lesen.

    – Tobias Grunwald

    30. Oktober 2020 um 15:10 Uhr

Nicht sicher, ob es hilft, aber seit Java9du kannst einfach schreiben:

Stream.ofNullable(nullableCollection)
      .flatMap(Collection::stream)

Benutzer-Avatar
Didier L

Dein collectionAsStream() Methode kann zu einer Version vereinfacht werden, die noch einfacher ist als bei der Verwendung Optional:

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

Beachten Sie, dass es in den meisten Fällen wahrscheinlich besser ist, nur auf Nullheit zu testen, bevor Sie die Stream-Pipeline erstellen:

if (collection != null) {
    collection.stream().filter(...)
} // else do nothing

Was Sie wollen, scheint nur nützlich zu sein, wenn Sie den Stream zurückgeben müssen (einschließlich für Flatmapping) oder ihn vielleicht mit einem anderen verketten müssen.

Benutzer-Avatar
alltej

Beim Herunterladen der Bibliothek org.apache.commons.collections4 ist keine Option, Sie können einfach Ihre eigene Wrapper-/Convenience-Methode schreiben.

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return collection == null ? ( Stream<T> ) Collections.emptyList().stream() 
                              : collection.stream();
}

Oder verpacken Sie die Sammlung mit Optional.ofNullable

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return Optional.ofNullable(collection)
            .orElse( Collections.emptySet()).stream();
}

Sie können so etwas verwenden:

public static void main(String [] args) {
    List<String> someList = new ArrayList<>();
    asStream(someList).forEach(System.out::println);
}

public static <T> Stream<T> asStream(final Collection<T> collection) {
    return Optional.ofNullable(collection)
            .map(Collection::stream)
            .orElseGet(Stream::empty);
}

1175940cookie-checkNullsichere Sammlung als Stream in Java 8

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy