java8 stream的collect 三個引數

2021-09-03 01:37:11 字數 1366 閱讀 5602

collect方法有兩個過載:

第乙個接收的是collector型別的,可以直接用collectors這類工具傳方法引用。

第二個接收的是三個引數的,

supplier:乙個能創造目標型別例項的方法。accumulator:乙個將當元素新增到目標中的方法。combiner:乙個將中間狀態的多個結果整合到一起的方法(併發的時候會用到)。接著看**:

stream stream = stream.of(1, 2, 3, 4).filter(p -> p > 2);

list result = stream.collect(() -> new arraylist<>(), (list, item) -> list.add(item), (one, two) -> one.addall(two));

/* 或者使用方法引用 */

result = stream.collect(arraylist::new, list::add, list::addall);

這個例子即為過濾大於2的元素,將剩餘結果收集到乙個新的list中。

第乙個函式生成乙個新的arraylist(最後返回的也是這個)

第二個函式的第乙個引數是前面生成的arraylist物件,第二個引數是stream中包含的元素,函式體就是把stream中的元素加入arraylist物件中。第二個方法被反覆呼叫直到原stream的元素被消費完畢;

第三個函式也是接受兩個引數,這兩個都是arraylist型別的,第乙個引數是第乙個函式建立的list,第二個引數,由於在並行的時候會建立多個list儲存並行時各個執行緒所計算完的結果,沒看過原始碼,我猜測應該是乙個執行緒對應乙個list儲存結果,每個執行緒都會呼叫第二個函式進行消費當前執行緒所需要處理的資料,如果建立了n個執行緒,那麼就會有n個結果,然後這些結果就乙個乙個傳進第三個函式的第二個引數。

所以,以原始資料是list為例,stream並行的原理難道就是:

一、根據collect第乙個引數建立乙個list例項(最終得到的也是這個)。

一、把stream的原始list資料劃分為n塊,然後分別交給n個執行緒。

二、每個執行緒根據自己得到的那塊list資料執行相應操作,每個執行緒一開始也是使用collect傳進來的第乙個函式建立新的list例項,然後使用collect的第二個函式消費當前執行緒需要處理的那一塊list原始資料,然後得到結果。

三、等所有執行緒執行完畢,得到n個結果(每個結果都是list),此時呼叫n次第三個函式。。第三個函式的第乙個引數為第一步建立的list,第二個引數則是各個執行緒執行完畢得到的結果list,平行計算時有多少個結果list就執行多少次。

四、執行完畢後,返回第一步建立的list

Java8 Stream經典示例

示例一 class user public int getid public string tostring 現在有乙個list的集合,如何把這個list轉換成map其中,key是user id,value是user物件 如下 listusers arrays.aslist new user 1,t...

Java8 Stream 中間操作

1 filter 過濾,接收lambda,從流中排除某些元素 內部迭代 迭代操作有stream api完成 test public void test1 終止操作 一次性執行全部內容 stream.foreach system.out println 外部迭代 test public void te...

JAVA8 stream 流相關操作

1.查詢流中滿足條件的第乙個元素 集合 stream filter item 條件 findany get 集合 stream filter item 條件 findfirst get 2.內迴圈 集合 stream foreach item 3.將集合轉換為map function.identit...