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