java 8流自定义收集器_Java 8编写自定义收集器简介

java 8流自定义收集器

Java 8引入了收集器的概念。 大多数时候,我们几乎不使用Collectors类中的工厂方法,例如collect(toList())toSet()或其他更有趣的方法,例如counting()groupingBy() 。 实际上,没有多少人真正去研究如何定义和实现收集器。 让我们从分析Collector<T, A, R>真正含义及其工作原理开始。

Collector<T, A, R>充当流的“接收 ” –流将项(一个接一个)推入收集器,最后应产生一些“ 收集 ”值。 在大多数情况下,这意味着通过累积元素或将流减少为更小的内容(例如, counting()很少的元素的toList()收集器)来构建集合(如toList() )。 每个收集器都接受类型T项,并产生类型R聚合(累积)值(例如R = List<T> )。 泛型A简单定义了中间可变数据结构的类型,在此期间,我们将使用它来累积T型项。 类型A可以但不必与R相同-简单来说,我们用来从输入Stream<T>收集项目的可变数据结构可以不同于实际的输出收集/值。 话虽如此,每个收集器都必须实现以下方法:

interface Collector<T,A,R> {Supplier<A>          supplier()BiConsumer<A,T>      acumulator() BinaryOperator<A>    combiner() Function<A,R>        finisher()Set<Characteristics> characteristics()
}
  • supplier()返回一个函数,该函数创建一个累加器实例–可变数据结构,我们将使用该函数来累加类型T输入元素。
  • accumulator()返回一个函数,该函数将累加累加器和类型T一项,即累加累加器。
  • combiner()用于将两个累加器合并为一个。 它在并行执行收集器时使用,首先拆分输入Stream<T>并首先独立收集部分。
  • finisher()使用累加器A并将其转换为R类型的结果值,例如collection。 所有这些听起来都很抽象,所以让我们做一个简单的例子。

显然,Java 8没有为Guava提供ImmutableSet<T>的内置收集器。 但是,创建一个非常简单。 请记住,为了迭代地构建ImmutableSet我们使用ImmutableSet.Builder<T> –这将是我们的累加器。

import com.google.common.collect.ImmutableSet;public class ImmutableSetCollector<T> implements Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> {@Overridepublic Supplier<ImmutableSet.Builder<T>> supplier() {return ImmutableSet::builder;}@Overridepublic BiConsumer<ImmutableSet.Builder<T>, T> accumulator() {return (builder, t) -> builder.add(t);}@Overridepublic BinaryOperator<ImmutableSet.Builder<T>> combiner() {return (left, right) -> {left.addAll(right.build());return left;};}@Overridepublic Function<ImmutableSet.Builder<T>, ImmutableSet<T>> finisher() {return ImmutableSet.Builder::build;}@Overridepublic Set<Characteristics> characteristics() {return EnumSet.of(Characteristics.UNORDERED);}
}

首先,仔细研究泛型。 我们的ImmutableSetCollector接受类型T输入元素,因此它适用于任何Stream<T> 。 最后,将产生预期的ImmutableSet<T>ImmutableSet.Builder<T>将成为我们的中间数据结构。

  • supplier()返回创建新ImmutableSet.Builder<T>的函数。 如果您不熟悉Java 8中的lambda,则ImmutableSet::builder() -> ImmutableSet.builder()的简写。
  • accumulator()返回一个函数,该函数采用builder和一个T类型的元素。 它只是将上述元素添加到构建器中。
  • combiner()返回一个函数,该函数将接受两个生成器,并通过将一个中的所有元素添加到另一个中并返回后者来将它们变成一个。 最后finisher()返回一个函数,该函数会将ImmutableSet.Builder<T>转换为ImmutableSet<T> 。 同样,这是以下形式的简写语法: builder -> builder.build()
  • 最后但并非最不重要的一点是, characteristics()告知JDK我们的收集器具有什么功能。 例如,如果ImmutableSet.Builder<T>是线程安全的(不是),我们也可以说Characteristics.CONCURRENT

现在,我们可以使用collect()在所有地方使用自定义收集器:

final ImmutableSet<Integer> set = Arrays.asList(1, 2, 3, 4).stream().collect(new ImmutableSetCollector<>());

但是创建新实例有点冗长,因此我建议创建静态工厂方法,类似于JDK所做的:

public class ImmutableSetCollector<T> implements Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> {//...public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() {return new ImmutableSetCollector<>();}
}

从现在开始,我们只需键入以下命令即可充分利用我们的自定义收集器: collect(toImmutableSet()) 。 在第二部分中,我们将学习如何编写更复杂和有用的收集器。

更新资料

@akarazniewicz 指出收藏家只是折叠的冗长实现。 由于我与褶皱之间的爱与恨关系,我不得不对此发表评论。 Java 8中的收集器基本上是Scala中最复杂的折叠类型的面向对象封装,即GenTraversableOnce.aggregate[B](z: ⇒ B)(seqop: (B, A) ⇒ B, combop: (B, B) ⇒ B): Baggregate()就像fold() ,但是需要额外的combop才能将两个B型累加器组合为一个。 将其与收集器进行比较,参数z来自seqop() supplier()seqop()归约运算是一个accumulator()combop是一个combop combiner() 。 用伪代码可以编写:

finisher(seq.aggregate(collector.supplier())(collector.accumulator(), collector.combiner()))

GenTraversableOnce.aggregate()在可能同时进行缩减时使用GenTraversableOnce.aggregate()就像收集器一样)。

翻译自: https://www.javacodegeeks.com/2014/07/introduction-to-writing-custom-collectors-in-java-8.html

java 8流自定义收集器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spyder pyecharts不显示_165Hz+1ms仅需千元左右 优派VX2771HDPRO显示器

VX2771-HD-PRO应该是前些时间比较受欢迎的电竞显示器之一&#xff0c;不足千元的售价(最近价格又涨回千元以上了)就可以拥有一台165Hz的1080P显示器&#xff0c;性价比还真的蛮高的。国庆在家&#xff0c;而且最近游戏大作不断&#xff0c;赶紧入手一台玩一玩。一、外观赏析开箱…

linux远程安装文件,通过image文件远程安装已经配置的Linux

smallwl 于 2006-08-29 00:08:53发表:一. 制作initrd文件1. 选择操作系统,这里就用FC2.0吧.2. 安装busybox.在这里, 需要一些命令去做一些事情, 比如fdisk, ls ,mv……如果把所有这些文件都做到initrd中,这个文件会太庞大了, busybox就是为了解决这个问题的.从www.busybox.net上…

elementui表格中tip设置_VUE2.0+ElementUI2.0表格el-table:表头扩展el-tooltip

ElementUI2.0的表格的扩展&#xff1a;如果要实现鼠标移到表头有注释或者弹框该怎么添加呢&#xff1f;可以使用table的rander-header属性&#xff0c;render出一个el-tooltip文字提示而文字提示的内容暂存到label-class-name属性里(当然损失了label-class-name的应有功能)在el…

Java 11新字符串方法的基准

在检查Java 11的新增功能时&#xff0c;我发现String类有几种新方法。 所以我想用旧的做事方法和使用新方法做一个微基准测试。 这些新方法是&#xff1a; boolean isBlank()String strip()Stream lines()再次测试isBlank&#xff08;&#xff09;&#xff0c;trim&#xff08…

与安装应用签名不同怎么解决_TCL电视下载软件后不能安装怎么办?一招教你解决...

最近,不少TCL用户都遇到了在当贝市场下载软件后不能安装的问题,那么遇到这种问题该怎么解决呢?首先我们先分析下为什么会出现这种情况!原因:这种情况大多数是因为安装包没有下载完毕或安装包破损导致的,也可能是安装包不适合在你的系统版本中安装,需要最新版本的系统。解决方法…

linux命令基本格式教程,Linux命令基本格式(详解版)

本节开始&#xff0c;我们不会再见到图形界面了&#xff0c;因为对服务器来讲&#xff0c;图形界面会占用更多的系统资源&#xff0c;而且会安装更多的服务、开放更多的端口&#xff0c;这对服务器的稳定性和安全性都有负面影响。其实&#xff0c;服务器是一个连显示器都没有的…

kettle 内存设置_【转】kettle 的内存设置及输出日志的时间类型

本文转载自&#xff1a;http://blog.csdn.net/dqswuyundong/archive/2010/10/19/5952004.aspx设置kettle的内存REM ******************************************************************REM ** Set java runtime options **REM ** Change…

java面试简历精通n_面试3年java程序员说精通spring源码 听完后觉得还是劝退好

面试官&#xff1a;看你简历上写了读过Spring源码&#xff0c;是吗&#xff1f;我&#xff1a; 是的面试官&#xff1a;读过哪些部分的?我&#xff1a;读过Spring的启动过程源码&#xff0c;比如扫描包、执行Bean工厂后置处理器、Bean的生成过程等(自信满满)面试官&#xff1a…

linux 递归创建线程,[linux]二叉树的建立及其递归遍历(C语言实现)

#二叉树的特点&#xff1a;每一个节点最多有两棵子树&#xff0c;所以二叉树中不存在度大于2的节点&#xff0c;注意&#xff0c;是最多有两棵&#xff0c;没有也是可以的 左子树和右子树是有顺序的&#xff0c;次序不能颠倒&#xff0c;这点可以在哈夫曼编码中体现&#xff0c…

delphi image 编辑器_照片拼图编辑器app下载-照片拼图编辑器下载 v1.0.0 安卓版

照片拼图编辑器是一个专业的照片编辑的app&#xff0c;app里面有很多的拼图工具&#xff0c;模板、水印、滤镜、贴图等等随便你用&#xff0c;可以将图片拼接成多种样式&#xff0c;满足你的各种需求。你想要什么样的效果都可以&#xff0c;赶紧来下载吧&#xff01;应用介绍&a…

java gradle入门_Gradle入门:我们的第一个Java项目

java gradle入门这篇博客文章描述了如何使用Gradle编译和打包一个简单的Java项目。 我们的Java项目只有一个要求&#xff1a; 我们的构建脚本必须创建一个可执行的jar文件。 换句话说&#xff0c;我们必须能够使用以下命令运行程序&#xff1a; java -jar jarfile.jar让我们…

非核心版本的计算机上_哪个版本的Microsoft Office最好使用、来占用最少的资源...

使用过多个版本的Microsoft Office和WPS Office。让我推荐几个版本&#xff1a;Microsoft Office 2003和Microsoft Office 2007是两个资源最密集的版本(不考虑旧版本的Office)&#xff0c;除非它们是特别旧的计算机&#xff0c;否则不建议安装。对于十年前的旧计算机&#xff0…

linux条件测试的三种,shell编程之条件测试 | 旺旺知识库

一、条件测试语法&#xff1a;test 测试内容[ 测试内容 ] ##注意中括号与测试内容间有空格[[ 测试内容 ]](( 测试内容 )) ##只能用于测试数值大小&#xff0c;后面详解前三种测试语法基本等同。二、数值测试&#xff1a;2.1 常见的数值测试&#xff1a;int1 -eq int2 如…

是vans_硬核复刻,就服VANS棋盘格

近几年复刻已成为 Sneaker 圈的新趋势&#xff0c;各大品牌纷纷将自家经典且具有年代感的鞋款复刻再造。而这其中最硬核的还要属 VANS &#xff0c;在今年三月释出 VANS X FAST TIMES 鞋款&#xff0c;标志性的棋盘格元素加上醒目亮眼的红字 Logo &#xff0c;为穿着者带来不一…

使用SDKMAN管理多个Java SDK! 轻松

SDKMAN&#xff01; 是用于管理多个软件开发套件的并行版本的便捷工具。 该工具对Java开发人员特别有用&#xff0c;因为它支持JVM的SDK&#xff0c;例如Java&#xff0c;Groovy&#xff0c;Scala&#xff0c;Kotlin和Ceylon。 还支持Gradle&#xff0c;Maven&#xff0c;Sprin…

linux wordpress伪静态,wordpress程序在win和Linux系统下的伪静态设置 - 张力博客

这是一篇很早就应该写的文章&#xff0c;而在昨天就有朋友问我&#xff0c;为什么不写一下关于wordpress的伪静态设置呢&#xff1f;今天这篇文章我就来跟大家说一下&#xff0c;关于wordpress程序在win和Linux系统下的伪静态设置方法。第一种&#xff1a;win系统下的wordpress…

Java并发编程实战_阿里P9整理分享的亿级流量Java高并发与网络编程实战PDF

前言为了帮助初级开发者快速掌握高并发、网络编程、微服务、海量数据的处理这些实用技术&#xff0c;本文以“理论范例”的形式对各个知识点进行了详细的讲解&#xff0c;力争让读者在实践中快速掌握相关知识。为了让有java、数据库和web基础的学生&#xff0c;初、中级java开发…

r语言 林元震_科学网—R语言简介 - 林元震的博文

R既是软件&#xff0c;也是语言&#xff0c;在GNU协议General Public Licence下免费发行&#xff0c;是1995年由新西兰奥克兰大学统计系的Ross Ihaka和Robert Gentleman基于S语言基础上共同开发的一种统计软件。现在由R开发核心小组(R Development Core Team)负责维护与更新&am…

英特尔 620 显卡 驱动 七代cpu_英特尔的智能“整体厨房”

其实&#xff0c;英特尔的战略非常容易理解。做最智能的“橱具”、最智能的“橱柜”、最智能的“橱电”。然后&#xff0c;顺理成章地构建起最智能“整体厨房”。再然后&#xff0c;用户可以在最优适配的软硬件环境中&#xff0c;专注于对数据的烹饪。当然&#xff0c;这是只是…

linux kvm安装win7,详解在 KVM 上安装 Win7 虚拟机

详解在 KVM 上安装 Win7 虚拟机发布时间&#xff1a;2017-04-04 21:09来源&#xff1a;互联网当前栏目&#xff1a;web技术类之前都是在用Linux 虚机&#xff0c;现在有需要用到Win7 虚机&#xff0c;才发现在 KVM 上安装 Win7 的过程远比想象中的复杂。本文就把其过程做个简单…