Java 8手動實現一個Collector

咱們看一下Stream中的collect的方法。java

collect(toList())方法由Stream裏的值生成一個列表,是一個及早求值的操做。數據庫

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

下面咱們看一下用法:app

運行結果如上圖。函數式編程

因爲不少Stream操做都是惰性求值,所以調用Stream上的一系列方法後,還須要最後調用相似collect這樣的及早求值的方法。函數

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

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

如今咱們看一下Collectors另一個方法。翻譯

固然Collectors中還有不少重載的groupingBy的方法,這裏咱們再也不關心。這個方法的意思就是對一個Stream中的元素進行分類,經過流中元素自己的一個方法的返回值做爲分類的標準,返回一個以剛纔返回值做爲key,包含相同方法返回相同key元素的類的List做爲Map的值。code

使用場景:

好比經過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函數式編程的詳盡的分析和翻譯,從中受益良多。謝謝。

相關文章
相關標籤/搜索