2017-01-11 21 views
17

Tôi đang tìm phương pháp có thể tạo luồng thu thập nhưng không an toàn. Nếu bộ sưu tập rỗng, luồng trống sẽ được trả về. Như thế này:Bộ sưu tập an toàn Null dưới dạng luồng trong Java 8

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

Tôi đã tạo ra phương pháp riêng của tôi:

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

Nhưng tôi tò mò, nếu có cái gì đó như thế này trong tiêu chuẩn JDK?

+6

Bạn nên cố gắng tránh những 'bộ sưu tập null' ở nơi đầu tiên. Cách tốt nhất là sử dụng bộ sưu tập trống để thay thế. –

+2

Có, tôi đồng ý, nhưng nếu bạn phụ thuộc vào thư viện khác của người khác, bạn không có lựa chọn. – Gondy

+0

Trong trường hợp đó bạn chỉ có thể thay thế bộ sưu tập mà bạn nhận được từ thư viện đó bằng thư viện rỗng khi nó trả về 'null'. Một chút giống như trong giải pháp của greg. –

Trả lời

19

Bạn có thể sử dụng org.apache.commons.collections4. CollectionUtils :: emptyIfNull chức năng:

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

Tôi thực sự thích giải pháp này, bởi vì rất đơn giản. Tuy nhiên, thư viện bên ngoài là cần thiết, nhưng trong thế giới của Maven và Gradle nó không phải là một vấn đề. Tôi biết tôi đã yêu cầu JDK8 nhưng dường như không có gì đơn giản này là có. – Gondy

22

Bạn có thể sử dụng Optional:

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

tôi đã chọn Collections.emptySet() tùy tiện như giá trị mặc định trong trường hợp collection là null. Điều này sẽ dẫn đến việc gọi phương thức stream() trống rỗng Stream nếu collection không có giá trị.

Ví dụ:

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

Output:

3 
0 

Cách khác, như marstran gợi ý, bạn có thể sử dụng:

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

'Optional.ofNullable (collection) .map (Bộ sưu tập :: stream) .orElse (Stream.empty());' là một giải pháp tương đương có thể mà bạn không phải chọn 'Collections.emptySet()'. – marstran

+5

Như đã đề cập bởi [@StuartMarks] (http://stackoverflow.com/users/1441122/stuart-marks) như _Use, Abstruse Use và Abuse_: [Quy tắC# 4] (https://youtu.be/Ej0sss6cq14? t = 27m51s): _Đó thường là một ý tưởng tồi khi tạo một 'Tùy chọn' cho mục đích duy nhất của các phương thức chuỗi từ nó để nhận giá trị_. –

+0

@DidierL Tôi không thể xem clip youtube đó ngay bây giờ, nhưng ấn tượng đầu tiên của tôi là tôi, nói chung, không đồng ý. Tôi sẽ kiểm tra nó ra sau ngày hôm nay. Trường hợp chúng ta có ở đây trông khá sạch sẽ với 'collection! = Null? collections.stream(): Stream.empty(); 'mặc dù. – marstran

1

Bạn có thể sử dụng một cái gì đó như thế:

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

thậm chí còn tốt hơn để bỏ qua đánh giá thay thế bằng cách sử dụng '.orElseGet (Stream :: empty)'. –

+0

Vâng, đó là sự thật :) –

6

phương pháp collectionAsStream() của bạn có thể được đơn giản hóa đến một phiên bản thậm chí đơn giản hơn khi sử dụng Optional:

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

Lưu ý rằng trong nhiều trường hợp, nó có thể tốt hơn để chỉ kiểm tra tính rỗng trước khi xây dựng đường ống luồng:

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

Điều bạn muốn dường như chỉ hữu ích khi bạn cần trả lại luồng (bao gồm cả bản đồ phẳng) hoặc có thể nối nó với một hình khác.

1

Nếu tải xuống thư viện org.apache.commons.collections4 không phải là một tùy chọn, bạn chỉ có thể viết trình bao bọc/tiện ích của riêng mình.

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

Hoặc gói các bộ sưu tập với Optional.ofNullable

public static <T> Stream<T> asStream(final Collection<T> collection) { 
    return Optional.ofNullable(collection) 
      .orElse(Collections.emptySet()).stream(); 
} 
Các vấn đề liên quan