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函数式编程的详尽的分析和翻译,从中受益良多。谢谢。
Java 8手动实现一个Collector的更多相关文章
- java web(一) 使用sql标签库+tomcat+mysql手动创建一个jsp练习总结
2016-09-0111:06:53 使用sql标签库+tomcat+mysql手动创建一个jsp 1. 1.1安装tomcat ...
- 原来热加载如此简单,手动写一个 Java 热加载吧
1. 什么是热加载 热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般不会用于正式的生产环 ...
- 计算机网络(13)-----java nio手动实现简单的http服务器
java nio手动实现简单的http服务器 需求分析 最近在学习HTTP协议,还是希望动手去做一做,所以就自己实现了一个http服务器,主要功能是将http请求封装httpRequest,通过解析 ...
- 用java从0生成一个简单的excel
用java从0生成一个简单的excel 目标 用代码实现对一个excel的基础操作,包括创建,插入文字,(好像就这些了),生成的excel可以用wps打开,如果直接用c++的文件流会生成假的xls表格 ...
- java web 手动部署项目步骤
java Web 手动部署项目步骤 1 在tomcat下面的webapps下面建立需要部署的文件夹(eg:demo);2 在demo下建立 WEB-INF WETA-INF src 文件夹;3 在sr ...
- 手动实现一个简易版SpringMvc
版权声明:本篇博客大部分代码引用于公众号:java团长,我只是在作者基础上稍微修改一些内容,内容仅供学习与参考 前言:目前mvc框架经过大浪淘沙,由最初的struts1到struts2,到目前的主流框 ...
- JDBC数据源(DataSource)数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用。
JDBC数据源(DataSource)的简单实现 数据源技术是Java操作数据库的一个很关键技术,流行的持久化框架都离不开数据源的应用. 2.数据源提供了一种简单获取数据库连接的方式,并能在内部通 ...
- 手动实现一个 IOC/DI 容器
第一章为源码解析. 第二章为实现一个简单的 IOC 容器. 第三章进阶 Spring 插件开发. 手动实现一个 IOC/DI 容器 上一篇文章里我们已经对 Spring 的源码有了一个大概的认识,对于 ...
- 手动写一个类支持foreach循环
之前初学时看过可以实现Iterable接口实现Iterator迭代器的支持,并且也支持foreach循环.现在学习了数据结构,手动写一个单链表支持foreach循环吧. 手写foreach循环步骤: ...
随机推荐
- TensorFlow安装环境的误区
安装py一定要注意安装的版本,我一开始安装的3.7版本的,现在还没有支持,另外,看清楚自己电脑是32位还是64位的
- Beginning DirectX11 Game Programming
DirectX11 or 10 made a big change comparing to DirectX9 The fixed-function pipeline was removed in D ...
- 节约内存:Instagram的Redis实践
Instagram可以说是网拍App的始祖级应用,也是当前最火热的拍照App之一,Instagram的照片数量已经达到3亿,而在Instagram里,我们需要知道每一张照片的作者是谁,下面就是Inst ...
- BZOJ 1193--马步距离
1193: [HNOI2006]马步距离 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2267 Solved: 1026[Submit][Stat ...
- Mac系统升级后在终端输入git命令时遇到的问题
Mac系统升级git会找不到并且报错:xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) ...
- python3笔记
python3 Python3 基本数据类型 Python 中有六个标准的数据类型: Numbers(数字) Python可以同时为多个变量赋值,如a, b = 1, 2. 一个变量可以通过赋值指向不 ...
- C#中给WebClient添加代理Proxy
效果图: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...
- ECSHOP和SHOPEX快递单号查询EMS插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- 密码发生器 南阳acm519
密码发生器 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全:如 ...
- class实现Stack
基于class实现一个存储string类型的Stack 头文件: //stack.h #include<vector> #include<string> class Stack ...