Collector都搞不清楚,寫什麼Java,一張圖搞定

目錄

1、用來做什麼的?

2、都有哪些用法?

3、源碼怎麼實現的?

4、總結

Collector都搞不清楚,寫什麼Java,一張圖搞定

 

最近一段時間比較忙,也不知道都在做些什麼。五一期間本來打算寫一篇的,但是一直有各種事情拖着也沒寫下來。今天繼續是計劃內的一篇文章collector。

1、用來做什麼的?

collectors直接翻譯就是收集器。主要的作用是就是將流中的數據進行收集整理。collectors主要還是配合stream來使用。平常的話也不會用到。

2、都有哪些用法?

Collectors可以幫我們完成的事情,例如:分組、排序(支持多字段排序)、最大值、最小值、平均值,簡單的來說,以前我們在數據上面用sql 去完成的聚合相關的操作,Collectors 都可以完成。可以參照stream那一篇。

3、源碼怎麼實現的?

Collectors到底是怎麼實現的呢?現在來看一下源碼,一起學習一下。

先看一下collect需要傳入的參數都有哪些。

Collector都搞不清楚,寫什麼Java,一張圖搞定

 

 

可以看到有兩種實現

一種實現就是傳入三個函數。

<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);

另外一種實現就是傳入一個collector。其實沒有本質上的區別。

list.stream().collect(Collectors.toList())

先看看最簡單的Collectors.toSet()實現。

public static <T>
    Collector<T, ?, Set<T>> toSet() {
        return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_UNORDERED_ID);
    }

從上面代碼可以看到toSet返回了一個CollectorImpl,CollectorImpl實現和上面的三個函數差不多。只有一個參數不一樣。

CollectorImpl(Supplier<A> supplier,
   BiConsumer<A, T> accumulator,
    BinaryOperator<A> combiner,
    Set<Characteristics> characteristics) {
     this(supplier, accumulator, combiner, castingIdentity(), characteristics   }

下面開始理解這個三個函數到底都在做什麼?

Supplier<A> supplier, supplier是主要創建一個新的對象返回。一般用來返回一個容器對象。

BiConsumer<A, T> accumulator, 主要是用來累加合併,將新的T和A進行融合。一般來說T放入a的集合中。

BinaryOperator<A> combiner,主要是用來對多線程的時候進行組裝。

Set<Characteristics> characteristics 最後一個參數主要是描述集合的特性,需要做什麼樣的操作。等下會有介紹。

具體流程是什麼樣的我們自己來實現一下

  List<String> list = Lists.newArrayList();
      list.add("香菜");
      list.add("聊遊戲");
      Supplier<Set<String>> supplier = ()-> new HashSet<>();
      BiConsumer<Set<String>, String> accumulator = (set, s) -> set.add(s);
      BiConsumer<Set<String>, Set<String>> combiner = (left,right)->{left.addAll(right);};
      Set<String> collect = list.stream().parallel().collect(supplier, accumulator, combiner);
      System.out.println(collect);

我們到底做了什麼?

R result = supplier.get();
for (T element : this stream)
        accumulator.accept(result, element);
return result;

多線程的情況下就像下面這張圖。

Collector都搞不清楚,寫什麼Java,一張圖搞定

 

而collect中只有一個參數,那就是Collector對象,java.util.stream.Collector 這是一個接口,其功能是將流處理的結果,匯聚處理成最終的一個可變對象(容器)。 這個接口有5個方法:

Supplier supplier(); 創建一個結果容器

BiConsumer accumulator(); 將元素合併到結果容器中

BinaryOperator combiner(); 將兩個結果容器合併

Function finisher(); 最終操作

Set characteristics();返回一個固定的特徵集合

特徵集合:

/**當前Collector支持併發,一般情況下UNORDERED也會一起放在characteristics中*/
      CONCURRENT,
      /** 當前Collector對操作元素是不會關心順序的的 */
      UNORDERED,
      /**當前Collector沒有Finisher*/
      IDENTITY_FINISH

 

看了源碼應該瞭解是怎麼回事了,具體的實現可以參照Collector 的實現,so easy。

4、總結

Collectors一個常用的collector工廠,這個工廠就是collect中常用的收集方式的實現。記住最重要的那張圖,一切就迎刃而解了。

 

人生不像做飯,不能等萬事俱備了才下鍋。

 

————————————————

《Java學習、面試;文檔、視頻資源免費獲取》

 

原文鏈接:https://blog.csdn.net/perfect2011/article/details/106065050

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章