在獲取流之前做空檢查的最佳/習慣用法是什麼?如何從可空對象中最好地創建Java 8流?
我有方法接收List
可能爲空。所以我不能只傳遞.stream()
就可以了。有沒有一些靜態助手會給我一個空的流,如果一個值爲空?
在獲取流之前做空檢查的最佳/習慣用法是什麼?如何從可空對象中最好地創建Java 8流?
我有方法接收List
可能爲空。所以我不能只傳遞.stream()
就可以了。有沒有一些靜態助手會給我一個空的流,如果一個值爲空?
我Stuart Marks同意list == null ? Stream.empty() : list.stream()
是要做到這一點(見his answer)的最好辦法,或者至少做到這一點的最好辦法在Java 9之前(請參閱下面的編輯),但我會留下這個答案來演示可選API的用法。
<T> Stream<T> getStream(List<T> list) {
return Optional.ofNullable(list).map(List::stream).orElseGet(Stream::empty);
}
編輯:爪哇9用參數作爲其唯一的元素添加的靜態方法Stream.<T>ofNullable(T)
,它返回給定null
參數空流,否則流。如果參數是一個集合,我們可以用flatMap
將它變成一個流。
<T> Stream<T> fromNullableCollection(Collection<? extends T> collection) {
return Stream.ofNullable(collection).flatMap(Collection::stream);
}
這不濫用可選API由斯圖爾特·馬克斯的討論,並在對比的是三元運算解決方案,還有一個空指針異常沒有機會(比如,如果你不重視和搞砸了操作數的順序)。它也可以與上界通配符一起使用,不需要SuppressWarnings("unchecked")
,這要歸功於flatMap
的簽名,因此您可以從T
的任何子類型的元素集合中獲得Stream<T>
。
我喜歡這個助手的例子,我可以重用一堆,並避免在我的代碼中散佈'Optional.orNullable'。 – checketts 2015-04-02 06:59:38
在List :: stream中不需要明確的類型參數'
@Holger,我做了這些改變,但我想知道什麼'Stream :: empty'實際上在幕後產生。一個匿名課程? – gdejohn 2015-04-02 11:05:59
我能想到的最好的方法是使用Optional
和orElseGet
方法。
return Optional.ofNullable(userList)
.orElseGet(Collections::emptyList)
.stream()
.map(user -> user.getName())
.collect(toList());
更新與@ Misha的建議使用Collections::emptyList
在ArrayList::new
最好使用'Collections :: emptyList'而不是'ArrayList :: new'。它使意圖更清楚,並且(稍微)更高效。 – Misha 2015-04-02 06:43:25
在其他答案中,Optional
實例是嚴格在同一個語句中創建和使用的。 Optional
類主要用於communicating with the caller關於存在還是不存在返回值,如果存在,則與實際值融合。完全在單一方法中使用它似乎沒有必要。
讓我提出以下建議較爲平淡的技術:
static <T> Stream<T> nullableListToStream(List<T> list) {
return list == null ? Stream.empty() : list.stream();
}
我猜三元運算符是有點家世不那麼高貴,這些天,但我認爲這是最簡單和最有效的解決方案。
如果我真的寫了這個(也就是說,對於一個真正的庫,不僅僅是堆棧溢出的示例代碼),我會放入通配符,以便流返回類型可以不同於List類型。哦,它可以是一個集合,因爲這是在哪裏定義的stream()
方法:
@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll) {
return coll == null ? Stream.empty() : (Stream<T>)coll.stream();
}
(警告抑制是因爲從Stream<? extends T>
投給Stream<T>
這是安全的必要,但是編譯器不知道那。)
阿帕奇公地collections4:
CollectionUtils.emptyIfNull(list).stream()
嗨piotrek;你的代碼可能是正確的,但在某些情況下會更好;例如,您可以解釋如何以及爲什麼這個提議的變更可以解決提問者的問題,或許還包括指向相關文檔的鏈接。這將使它對他們更有用,而且對尋求類似問題解決方案的其他網站讀者也更有用。 – 2016-08-17 09:36:50
不確定應該說明什麼。 apache commons-collections是最標準的java庫之一。它如何解決OP問題?它直接做OP所需要的 - 它從一個可爲空的列表中產生一個流 – piotrek 2016-08-17 17:09:59
我個人考慮零廢棄,使用可選儘可能儘管(微小)的性能開銷。所以我使用Stuart Marks的接口和基於gdejohn的實現,即
@SuppressWarnings("unchecked")
static <T> Stream<T> nullableCollectionToStream(Collection<? extends T> coll)
{
return (Stream<T>) Optional.ofNullable(coll)
.map(Collection::stream)
.orElseGet(Stream::empty);
}
我強烈建議在列表提供方的工作。 optionals的全部目的是不處理'null'引用。如果一個方法返回一個可能爲'null'的列表,它應該返回一個可選的。如果這是不可能的,你可以把它包裝成可選的(根據答案)。另外,你想用這個列表做一些事情,也就是說,如果它存在,你就要消費它。因此,只需在其上調用['Optional.ifPresent'](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ifPresent-java.util.function.Consumer-) 。 – Seelenvirtuose 2015-04-02 07:09:57