咱們看一下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函數式編程的詳盡的分析和翻譯,從中受益良多。謝謝。