一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解Java中Collector接口的組成

詳解Java中Collector接口的組成

2021-09-22 10:54只要你一直跑 Java教程

今天給大家帶來的是關于Java基礎的相關知識,文章圍繞著Collector接口的組成展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下

一、Collector常常出現的地方

java8引入了stream,Collector是與stream一起出現的,配合stream使用的好幫手,如果用過stream,我們應該都有寫過這樣的代碼

例子1:

?
1
lists.stream()....collect(Collectors.toList());

例子2:

?
1
lists.stream().collect(groupingBy(String::length));

這兩個例子中,toList()和groupingBy()返回的都是一個Collector對象,那么問題來了,什么是Collector?

二、什么是Collector

Collector其實是一個泛型接口,通過這個接口可以定義一系列的聚合操作,按照官方文檔的說法,Collector其實是提供mutable reduction operation,即可改變的減少操作。

常見的聚合操作有:

1.用StringBuilder拼接字符串

2.計算元素綜合的數據,比如sum, min, max, or average
這個reduction在Google翻譯是減少的意思,但是我不太對得上這個意思,覺得形容成聚合操作會更容易理解一點。

關于聚合操作,我們會在很多語言中遇到,比如mysql里面的group by操作,sum(),min(),max(),Count(),anyValue(),這些叫做aggregate function,即聚合操作

我理解這些操作的是類似的,只不過這些是在數據庫里面進行的,collector是在java代碼層進行的,他們的本質都是一樣的,他們都進行了多對一的轉換,將一系列的數據變成一個數據或者幾團數據。

三、Collector的使用

Collector是一個接口,它還有一個靜態工具類Collectors,Collectors提供了很多常見的聚合操作的實現,通常來說我們調用Collectors里面的方法就夠了,如果想要更多更復雜的實現也可以自定義一個collector,定義Collector的話,我們需要先了解Collector的組成

3.1 Collector的泛型類型

collector是一個泛型接口,那我們先從泛型的元素開始分析

Collector<T, A, R>

這個接口有三種類型,T代表流中元素的類型,A是中間結果容器的類型,R是最后返回的類型
比如一個字符串數組strings,對它進行這個操作

?
1
strings.stream()....collect(Collectors.toList());

toList()方法返回的Collector中,T就是String類型,A是List<String>類型,R是List<String>類型,如果不能理解可以繼續往下看

3.2 Collector 的組成

collector由四個方法組成和一個特性組成

組成 作用
Supplier 創建一個新的結果容器
accumulator 將一個新的元素(流中的元素)加入到結果容器中
combiner 接受兩個中間的結果容器,將它們合并成一個(并行流的時候)
finisher 將結果容器轉換成另一個類型(可選的)

characteristics 是一個枚舉特性集合,決定某些操作過程的特性,比如是否是并行的,是否需要轉換結果容器,是否是有序的,這些特性用來進行簡化操作,提供更好的性能。

一共有三個特性,在定義的時候可以選幾個來組成這個集合,它們是:

  • CONCURRENT :意味著這個同一個容器可以被多個線程調用accumulator方法進行操作
  • UNORDERED:意味著這個聚合操作不會保留元素的出現順序,一般是來說最后的結果容器是無序的(比如Set)才會使用
  • IDENTITY_FINISH:意味著finisher方法是Function.identity(),可以被省略,如果設置了的話,需要A類型可以能強制地轉換成R類型,否則會拋出異常。

關于Collector的四個方法,這里用一個流程圖來解釋這個過程

詳解Java中Collector接口的組成

3.3 舉例解釋Collector四個方法

下面通過Collectors里面提供的常見方法來詳細地說明Collector的組成

3.3.1 Example1- toList()

首先來看toList()方法的組成

?
1
2
3
4
5
public static <T> Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}

對于這個方法實現來說

  • supplier是 () -> ArrayList::new,提供的容器類型(A)是ArrayList
  • accumulator是List::add,將元素item加入到arrayList容器中,即

(intermediateCollector, item) -> intermediateCollector.add(item)

  • combiner是將兩個容器arrayList合并

(left, right) -> { left.addAll(right); return left;}

  • finisher是啥也不做,combiner之后的結果就直接返回來,所以R也是ArrayList的類型
  • characteristic是

Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));

IDENTITY_FINISH這個特性是說,不執行finisher函數,直接返回combiner之后的結果容器

3.3.2 Example2- joining()

joining有三個方法重載,我們這里先看最直觀的一個,它的實現是

?
1
2
3
4
5
6
public static Collector<CharSequence, ?, String> joining() {
    return new CollectorImpl<CharSequence, StringBuilder, String>(
            StringBuilder::new, StringBuilder::append,
            (r1, r2) -> { r1.append(r2); return r1; },
            StringBuilder::toString, CH_NOID);
}
  • supplier是StringBuilder::new,即:

() -> new StringBuilder();

容器A的類型是StringBuilder

  • accumulator是StringBuilder::append, 即

(intermediate, current)-> intermediare.append(current);

  • combiner是

(r1, r2) -> { r1.append(r2); return r1; }

即對于兩個中間的結果stringBuilder來說,combiner做的事情就是合并兩個stringBuilder,變成一個stringBuilder

  • finisher是StringBuilder::toString,對于最后的容器StringBuilder,finisher會將它轉換成String的類型,因此R的類型是String
  • characteristic是一個emptySet(),不包含任何特性

Collections.emptySet();

到此這篇關于詳解Java中Collector接口的組成的文章就介紹到這了,更多相關Collector接口的組成內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/lingfy1234/article/details/117887349

延伸 · 閱讀

精彩推薦
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
主站蜘蛛池模板: 日本另类z0zx高清 | 99年水嫩漂亮粉嫩在线播放 | 国产午夜成人无码免费看 | ck7788免费视频 | 亚洲第一在线 | 能播放18xxx18女同 | 男人的天堂在线观看入口 | 91噜噜噜噜色 | 美女脱一净二净不带胸罩 | 日韩aⅴ在线观看 | www.精品视频 | 精品福利视频一区二区三区 | 免费视频精品一区二区三区 | 福利国模私拍视频在线观看 | 97久久天天综合色天天综合色hd | 极品丝袜老师h系列全文阅读 | 99久久精品99999久久 | 无码任你躁久久久久久久 | 亚洲久草在线 | 美国复古性经典xxxxx | 桃乃木香奈作品在线观看 | 四虎4hu新地址入口 四虎1515h永久 | 免费看黄色一级 | 欧式午夜理伦三级在线观看 | 天海翼最新 | 无人区1在线观看 | 第一次出血videos | 成版人快猫永久破解版 | 香蕉动漫库 | 大胆人gogo888体艺术在线 | 日韩亚洲欧美综合一区二区三区 | 国产精品一区二区在线观看完整版 | 亚洲系列国产精品制服丝袜第 | kuaibo成人播放器 | 精品国产乱码久久久久久人妻 | 亚洲 欧美 制服 校园 动漫 | 免费看欧美一级特黄a大片一 | 国产亚洲毛片在线 | 极品ts赵恩静和直男激战啪啪 | 亚洲毛片基地4455ww | 国产成人精品实拍在线 |