怎么在java中创建一个自定义的collector
怎么在java中创建一个自定义的collector
简介
在之前的java collectors文章里面,我们讲到了stream的collect方法可以调用Collectors里面的toList()或者toMap()方法,将结果转换为特定的集合类。
今天我们介绍一下怎么自定义一个Collector。
Collector介绍
我们先看一下Collector的定义:

Collector接口需要实现supplier(),accumulator(),combiner(),finisher(),characteristics()这5个接口。
同时Collector也提供了两个静态of方法来方便我们创建一个Collector实例。
我们可以看到两个方法的参数跟Collector接口需要实现的接口是一一对应的。
下面分别解释一下这几个参数:
- supplier
Supplier是一个函数,用来创建一个新的可变的集合。换句话说Supplier用来创建一个初始的集合。accumulator
- accumulator
accumulator定义了累加器,用来将原始添加到集合中。
- combiner
combiner用来将两个集合合并成一个。
- finisher
finisher将集合转换为最终的集合类型。
- characteristics
characteristics表示该集合的特征。这个不是必须的参数。
有了这几个参数,我们接下来看看怎么使用这些参数来构造一个自定义Collector。
自定义Collector
我们利用Collector的of方法来创建一个不变的Set:
public static <T> Collector<T, Set<T>, Set<T>> toImmutableSet() {
return Collector.of(HashSet::new, Set::add,
(left, right) -> {
left.addAll(right);
return left;
}, Collections::unmodifiableSet);
}
上面的例子中,我们HashSet::new作为supplier,Set::add作为accumulator,自定义了一个方法作为combiner,最后使用Collections::unmodifiableSet将集合转换成不可变集合。
上面我们固定使用HashSet::new作为初始集合的生成方法,实际上,上面的方法可以更加通用:
public static <T, A extends Set<T>> Collector<T, A, Set<T>> toImmutableSet(
Supplier<A> supplier) {
return Collector.of(
supplier,
Set::add, (left, right) -> {
left.addAll(right);
return left;
}, Collections::unmodifiableSet);
}
上面的方法,我们将supplier提出来作为一个参数,由外部来定义。
看下上面两个方法的测试:
@Test
public void toImmutableSetUsage(){
Set<String> stringSet1=Stream.of("a","b","c","d")
.collect(ImmutableSetCollector.toImmutableSet());
log.info("{}",stringSet1);
Set<String> stringSet2=Stream.of("a","b","c","d")
.collect(ImmutableSetCollector.toImmutableSet(LinkedHashSet::new));
log.info("{}",stringSet2);
}
输出:
INFO com.flydean.ImmutableSetCollector - [a, b, c, d]
INFO com.flydean.ImmutableSetCollector - [a, b, c, d]
总结
本文介绍了Collector和自定义Collector的实例,希望能对大家有所帮助。
本文的例子https://github.com/ddean2009/learn-java-streams/tree/master/customCollector
欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com
怎么在java中创建一个自定义的collector的更多相关文章
- springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1.1 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeEx ...
- 在存放源程序的文件夹中建立一个子文件夹 myPackage。例如,在“D:\java”文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage)。在 myPackage 包中创建一个YMD类,该类具有计算今年的年份、可以输出一个带有年月日的字符串的功能。设计程序SY31.java,给定某人姓名和出生日期,计算该人年龄,并输出该人姓名、年龄、出生日期。程序使用YM
题目补充: 在存放源程序的文件夹中建立一个子文件夹 myPackage.例如,在“D:\java”文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage).在 m ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- java中创建线程的方式
创建线程的方式: 继承thread 实现runnable 线程池 FurureTask/Callable 第一种:继承thread demo1: public class demo1 { public ...
- JAVA中创建线程池的五种方法及比较
之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...
- Java中创建操作文件和文件夹的工具类
Java中创建操作文件和文件夹的工具类 FileUtils.java import java.io.BufferedInputStream; import java.io.BufferedOutput ...
- 如何创建一个自定义jQuery插件
简介 jQuery 库是专为加快 JavaScript 开发速度而设计的.通过简化编写 JavaScript 的方式,减少代码量.使用 jQuery 库时,您可能会发现您经常为一些常用函数重写相同的代 ...
- JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下: 一.继承Thread类来创建线程 1.创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run( ...
- Eclipse中创建一个新的SpringBoot项目
在Eclipse中创建一个新的spring Boot项目: 1. 首先在Eclipse中安装STS插件:在Eclipse主窗口中点击 Help -> Eclipse Marketplace... ...
随机推荐
- 是什么是递归?-[all]-[编程理论]
递归是所有编程语言中,都会讨论到的一个问题. Content Of Table 递归的通俗认识 编程领域的抽象 一个最简单的示例 一点总结 栈溢出问题 本示例的一点拓展说明 ### 递归的通俗认识 编 ...
- 1035 Password (20分)(水)
To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...
- spring中BeanPostProcessor之一:InstantiationAwareBeanPostProcessor(03)
前面介绍了InstantiationAwareBeanPostProcessor后置处理器的postProcessBeforeInstantiation和postProcessAfterInstant ...
- RHCS概述
RHCS概述 创建RHCS集群环境 创建高可用Apache服务 1 创建RHCS集群环境 1.1 问题 准备四台KVM虚拟机,其三台作为集群节点,一台安装luci并配置iSCSI存储服务,实现如下功能 ...
- Navicat安装教程
Navicat安装教程 1.下载: 链接:https://pan.baidu.com/s/1uLlstPYrsjaNhZqVu9aFfQ 提取码:393r 2.下载完成之后如图所示: 首先安装第二个, ...
- 谈谈CSS3中display属性的Flex布局(弹性布局)
最近为了微信小程序,回忆起之前有接触过的弹性布局(display:Flex) 网上摘录的原文地址:https://www.cnblogs.com/xuyuntao/articles/6391728.h ...
- django、celery异步发邮件
django.celery异步发邮件 django自带的send_mail发邮件功能执行发邮件功能会因为网络的原因造成花费的时间过长,为了解决这个问题,可以用celery + redis代替 安装包: ...
- Python操作rabbitmq系列(一)
从本文开始,接下来的内容,我们将讨论rabbitmq的相关功能.我的这些文章,最终是要实现一个项目(具体是什么暂不透露).前面每一篇,都是在为这个系统做准备.rabbitmq,是我们这个项目的关键部分 ...
- rdd简单操作
1.原始数据 Key value Transformations(example: ((1, 2), (3, 4), (3, 6))) 2. flatMap测试示例 object FlatMapTr ...
- 表字段或表名出现Mysql关键字或保留字导致问题 Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have
MySQL 5.7使用的关键字和保留字 https://dev.mysql.com/doc/refman/5.7/en/keywords.html 当我们建表的时候如果使用了关键字或者保留字,则在执行 ...