2017-03-09 255 views
5

我有包含字符串ID的集合idList。 函數getCollection返回單個ID項目集合(類型MyType)。此外,它可能會返回null。Java Stream:在列表中聚合所有非空集合在map()中

因此,對於idList中的許多ID,我會得到一些空值和一些集合。

我們的目標是收集所有getCollection對一組ID到最終列表的回覆。

我想象像

List<MyType> reply = idList.stream().map(id -> getCollection(id)) 
     .filter(p -> p != null).collect(Collectors.toList()); 

,但它似乎並沒有被有效的表達。如何使其有效?

另外,這個實現的性能呢?

回答

4

您需要使用flatMap -

List<MyType> reply = idList.stream() 
    .map(id -> getCollection(id)) 
    .filter(collection -> collection != null) 
    .flatMap(Collection::stream) 
    .collect(Collectors.toList()); 

如果你正在考慮的mapflatMap操作之間的差異,那麼你可以諮詢this excellent answer -

兩個地圖和flatMap可應用到一個流和他們都 返回一個流。不同之處在於映射操作爲每個輸入值生成一個輸出值 ,而flatMap操作 爲每個輸入值產生任意數量(零個或多個)值。

這反映在每個操作的參數中。

映射操作採用函數,該函數針對輸入流中的每個值 調用並生成一個結果值,該結果值將發送到 輸出流。

flatMap操作採用的概念上想要 消費一個值併產生任意數量的值的函數。但是,在Java中, ,因爲方法只能返回零個或一個值,所以返回任意數量的值的方法非常麻煩。人們可以想象一個API,其中flatMap的mapper函數取值, 返回一個數組或值列表,然後將其發送到 輸出。考慮到這是流庫,一個特別合適的方式 來表示任意數量的返回值是映射器函數本身返回一個流!由映射器返回的流 的值從流中排出並傳遞到 輸出流。每次調用 映射器函數返回的值的「塊」在輸出流中根本不會被區分,因此輸出被稱爲已被「展平」。

典型用法是爲flatMap的mapper函數返回 Stream.empty()如果​​它想發送零值,或者類似 Stream.of(a,b,c)如果它想返回多個值。但當然 任何流可以返回。

+0

使用flatMap的原因的簡要說明也有助於他人理解 –

+0

@ManuelS。如果你點擊藍色的flatMap鏈接,將會有一個關於flatMap的簡要說明。 – John

+0

flatmap需要流getCollection()返回列表?也許你需要像這樣改變你的代碼...'stream()。map(id - > getCollection(id))。flatMap(List :: stream)' –