2017-01-11 67 views
17

Poszukuję metody, która może generować strumień kolekcji, ale ma wartość zerową. Jeśli kolekcja ma wartość NULL, zwracany jest pusty strumień. Tak:Null safe Kolekcja jako strumień w języku Java 8

Utils.collectionAsStream(collection).filter(...); 

Stworzyłem własną metodę:

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

Ale jestem ciekaw, czy coś jest nie tak w standardzie JDK?

+6

należy starać się unikać 'kolekcję null' w pierwszej kolejności. Najlepszą metodą jest zamiast tego używanie pustej kolekcji. –

+2

Tak, zgadzam się, ale jeśli polegasz na czyjejś bibliotece, nie masz wyboru. – Gondy

+0

W takim przypadku można po prostu zastąpić kolekcję otrzymaną z tej biblioteki pustym, gdy zwróci 'null'. Trochę jak w rozwiązaniu Grega. –

Odpowiedz

19

Można użyć org.apache.commons.collections4. CollectionUtils :: emptyIfNull function:

org.apache.commons.collections4.CollectionUtils.emptyIfNull(list).stream().filter(...); 
+0

Naprawdę lubię to rozwiązanie, ponieważ jest bardzo proste. Jednak biblioteka zewnętrzna jest wymagana, ale w świecie Mavena i Gradle nie stanowi to problemu. Wiem, że pytałem o JDK8, ale najwyraźniej nic nie jest tak proste. – Gondy

22

Można użyć Optional:

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

Wybrałem Collections.emptySet() arbitralnie jako wartość domyślna w przypadku collection jest null. Spowoduje to wywołanie metody stream() wywołującej pustą Stream, jeśli collection ma wartość null.

Przykład:

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()); 

wyjściowa:

3 
0 

Alternatywnie, jako marstran zasugerował, można użyć:

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

'Opcjonalny.zakładki (kolekcja) .map (Kolekcja :: strumień) .orElse (Stream.empty());' jest możliwym równoważnym rozwiązaniem, w którym nie trzeba wybierać 'Collections.emptySet()'. – marstran

+5

Jak wspomniano w [@StuartMarks] (http://stackoverflow.com/users/1441122/stuart-marks) jako _Użyj, nieostrożne użycie i nadużywanie_: [Zasada # 4] (https://youtu.be/Ej0sss6cq14? t = 27m51s): Zasadniczo nie jest dobrym pomysłem utworzenie "Opcjonalnie" wyłącznie w celu połączenia metod, aby uzyskać wartość_. –

+0

@DidierL Nie mogę teraz oglądać tego klipu na youtube, ale moje pierwsze wrażenie jest takie, że ogólnie się nie zgadzam. Sprawdzę to później dzisiaj. Sprawa, którą tu mamy, wygląda całkiem czysto dzięki 'kolekcji! = Null? collections.stream(): Stream.empty(); 'chociaż. – marstran

1

Można użyć coś takiego:

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()); 
} 
+0

jeszcze lepiej leniwie ocenić alternatywę za pomocą '.orElseGet (Stream :: empty)'. –

+0

Tak, to prawda :) –

6

Twoja metoda collectionAsStream() można uprościć do wersji nawet prostszy niż przy użyciu Optional:

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

pamiętać, że w większości przypadków, to prawdopodobnie lepiej przetestować pod kątem nieważności przed zbudowaniem potoku:

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

To, czego chcesz, wydaje się być użyteczne tylko wtedy, gdy musisz zwrócić strumień (w tym w przypadku mapowania płaskiego) lub połączyć go z innym.

1

Jeśli pobieranie biblioteki org.apache.commons.collections4 nie jest opcją, możesz po prostu napisać własną metodę otoki/wygody.

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

Albo owijanie kolekcję o Optional.ofNullable

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