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函数式编程的详尽的分析和翻译,从中受益良多。谢谢。

posted on 2018-02-01 15:26  雪皓梅丹  阅读(1818)  评论(0编辑  收藏  举报