Java 8手動實現一個Collector


我們看一下Stream中的collect的方法。

collect(toList())方法由Stream里的值生成一個列表,是一個及早求值的操作。

Stream的of方法使用一個初始值生成新的Stream。事實上,collect的使用方法不僅限於此,它是一個非常通用的強大結構。

下面我們看一下用法:

運行結果如上圖。

由於很多Stream操作都是惰性求值,因此調用Stream上的一系列方法后,還需要最后調用類似collect這樣的及早求值的方法。

Collectors這個類中有很多自定義的Collector,顧名思義Collector的字面意思是收集器,意思就是對Stream流里面的元素進行收集,按照收集器的方式進行收集。

例如上面的Collectors.toList()收集器,收集成了List。

現在我們看一下Collectors另外一個方法。

當然Collectors中還有很多重載的groupingBy的方法,這里我們不再關心。這個方法的意思就是對一個Stream中的元素進行分類,通過流中元素本身的一個方法的返回值作為分類的標准,返回一個以剛才返回值作為key,包含相同方法返回相同key元素的類的List作為Map的值。

使用場景:

比如通過jpa從數據庫中查出了一個包含多個結果的List。此時我們需要對List中的元素進行分類,比如我們想把相同年齡的分在一起,這時這個方法就很合適。

Map<Object, List> result = list.Stream.collect(Collectors.groupingBy(Bean::getAge));

這樣我們就對list中的Bean按照年齡進行分類。

下面我們自己手動實現一個這樣的Collectors.groupingBy()。

package mycollector;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import java.util.stream.Collector.Characteristics; public class MyCollector { @SuppressWarnings("unchecked") public static <T, R extends Map<M, List<T>>, M> Collector<T, R, R> groupingby(Function<T, M> classifier) { Supplier<R> supplier = () -> { return (R)new HashMap<M, List<T>>(); }; BiConsumer<R, T> biConsumer = (m, t) -> { M r = classifier.apply(t); if(!m.containsKey(r)) m.put(r, new ArrayList<T>()); m.get(r).add(t); }; BinaryOperator<R> binaryOperator = (R left, R right) -> { left.putAll(right); return left; }; return Collector.of(supplier, biConsumer, binaryOperator, Characteristics.IDENTITY_FINISH); } }

下面然我們進行測試,輸入幾個字符串按照字符串的長度進行分類。

 

好了就是這些。

以上的內容大部分來自王群鋒先生翻譯的《java 8函數式編程》一書。感謝原著作者和王群鋒先生在書中對java函數式編程的詳盡的分析和翻譯,從中受益良多。謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM