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

相关文章
相关标签/搜索