- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java函数式编程(十):收集器由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前面我们已经用过几次collect()方法来将Stream返回的元素拼成ArrayList了。这是一个reduce操作,它对于将一个集合转化成另一种类型(通常是一个可变的集合)非常有用。collect()函数,如果和Collectors工具类里的一些方法结合起来使用的话,能提供极大的便利性,本节我们将会介绍到.
我们还是继续使用前面的Person列表作为例子,来看一下collect()方法到底有哪些能耐。假设我们要从原始列表中找出所有大于20岁的人。下面是使用了可变性和forEach()方法实现的版本:
。
我们使用filter()方法来从列表中过滤出了所有年龄大于20的人。然后,在forEach方法里,我们将元素添加到一个在前面已经初始化好的ArrayList中。我们先看下这段代码的输出结果,一会儿再去重构它.
。
程序输出的结果是对的,不过还有点小问题。首先,把元素添加到集合中,这种属于低级操作——它是命令式的,而非声明式的。如果我们想把这个迭代改造成并发的,还得去考虑线程安全的问题——可变性使得它难以并行化。幸运的是,使用collect()方法可以很容易解决掉这个问题。来看下如何实现的.
collect()方法接受一个Stream并将它们收集到一个结果容器中。要完成这个工作,它需要知道三个东西:
+如何创建结果容器(比如说,使用ArrayList::new方法) +如何把单个元素添加到容器中(比如使用ArrayList::add方法) +如何把一个结果集合并到另一个中(比如使用ArrayList::addAll方法) 。
对于串行操作而言,最后一条不是必需的;代码设计的目标是能同时支持串行和并行的.
我们把这些操作提供给collect方法,让它来把过滤后的流给收集起来.
。
。
这段代码的结果和前面一样,不过这样写有诸多好处.
首先,我们编程的方式更聚焦了,表述性也更强,清晰的传达了你要把结果收集到一个ArrayList里去的目的。collect()的第一个参数是一工厂或者生产者,后面的参数是一个用来收集元素的操作.
第二,由于我们没有在代码中个执行显式的修改操作,可以很容易并行地执行这个迭代。我们让底层库来完成修改操作,它自己会处理好协作及线程安全的问题,尽管ArrayList本身不是线程安全的——干的漂亮.
如果条件允许的话,collect()方法可以并行地将元素添加到不同的子列表中,然后再用一个线程安全的方式将它们合并到一个大列表里(最后一个参数就是用来进行合并操作的).
我们已经看到,相对于手动把元素添加到列表而言,使用collect()方法的好处真是太多了。下面我们来看下这个方法的一个重载的版本——它更简单也更方便——它是使用一个Collector作为参数。这个Collector是一个包含了生产者,添加器,以及合并器在内的接口——在前面的版本中这些操作是作为独立的参数分别传入方法中的——使用Collector则更简单并且可以复用。Collectors工具类提供了一个toList方法,可以生成一个Collector的实现,用来把元素添加到ArrayList中。我们来修改下前面那段代码,使用一下这个collect()方法.
。
使用了Collectors工具类的简洁版的collect()方法,可不止这一种用法。Collectors工具类中还有好几种不同的方法来可以进行不同的收集和添加的操作。比如说,除了toList()方法,还有toSet()方法,可以添加到一个Set中,toMap()方法可以用来收集到一个key-value的集合中,还有joining()方法,可以拼接成一个字符串。我们还可以将mapping(),collectingAndThen(),minBy(), maxBy()和groupingBy()等方法组合起来进行使用.
我们来用下groupingBy()方法来将人群按年龄进行分组.
。
。
只需简单的调用下collect()方法便能完成分组。groupingBy()接受一个lambda表达式或者方法引用——这种叫分类函数——它返回需要分组的对象的某个属性的值。根据我们这个函数返回的值,来把调用上下文中的元素放进某个分组中。在输出中可以看到分组的结果:
。
这些人已经按年龄进行了分组.
在前面这个例子中我们按人群的年龄对他们进行了分组收集。groupingBy()方法的一个变种可以按多个条件进行分组。简单的groupingBy()方法使用了分类器进行元素收集。而通用的groupingBy()收集器,则可以为每一个分组指定一个收集器。也就是说,元素在收集的过程中会途经不同的分类器和集合,下面我们将会看到.
继续使用上面这个例子,这回我们不按年龄分组了,我们只获取人的名字,按他们的年龄进行排序.
。
。
这个版本的groupingBy()接受两个参数:第一个是年龄,这是分组的条件,第二个是一个收集器,它是由mapping()函数返回的结果。这些方法都来自Collectors工具类,在这段代码中进行了静态的导入。mapping()方法接受两个参数,一个是映射用的属性,一个是对象要收集到的地方,比如说list或者set。来看下上面这段代码的输出结果:
。
。
可以看到,人们的名字已经按年龄进行分组了.
我们再来看一个组合的操作:按名字的首字母进行分组,然后选出每个分组中年纪最大的那位.
。
。
我们先是按名字的首字母进行了排序。为了实现这个,我们把一个lambda表达式作为groupingBy()的第一个参数传了进去。这个lambda表达式是用来返回名字的首字母的,以便进行分组。第二个参数不再是mapping()了,而是执行了一个reduce操作。在每个分组内,它使用maxBy()方法,从所有元素中递推出最年长的那位。由于组合了许多操作,这个语法看起来有点臃肿,不过整个读起来是这样的:按名字首字母进行分组,然后递推出分组中最年长的那位。来看下这段代码的输出,它列出了指定字母开头的那组名字中年纪最大的那个人.
。
。
我们已经领教到了collect()方法以及Collectors工具类的威力。在你的IDE或者JDK的官方文档里面,再花点时间去研究下Collectors工具类吧,熟悉下它提供的各种方法。下面我们将会用lambda表达式来完成一些过滤器的实现.
最后此篇关于Java函数式编程(十):收集器的文章就讲到这里了,如果你想了解更多关于Java函数式编程(十):收集器的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我刚刚更新了 Ruby,现在我在尝试启动 compass 时遇到以下错误: Encoding::CompatibilityError on line ["28"] of /usr/local/Cell
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 6 年前。
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试在我的 iOS 应用程序中开发可折叠/ Accordion 式的功能。这将是您可以在网站上找到的典型 FAQ 类型功能。我想点击标题,然后显示详细信息。 因为这是帮助部分,只有几个项目,我认
我正在尝试设计一个基于 REST 的 Web 服务来与我正在开发的农场动物管理系统进行交互。 为了详细说明问题,我收藏了动物 属于一个农场。每只动物都有自己的信息——例如姓名、身份证号、品种年龄等。因
我有 3 种不同的表单,其中复选框数量不同,每个部分基本上代表一个表单,因此当用户选择该部分中的复选框时,它会显示他们在该部分的总金额中 checkout 了多少 HTML
我有一份 32 页的 PDF 版家谱。与其将家谱全部放在一个非常大的 PDF 页面上(这是我想要的),不如将其格式化为一组 8 个单独的美国信纸大小的页面应该在整个宽度上缝合; 4 行这样就完成了树。
指SASS implementation for Java? : 在 Maven 目标编译包中自动编译 compass-style.org 样式表的最佳方法是什么? 我不想发送太多的自编译库,也不想通
鉴于以下 XAML... 我正在寻找一种绑定(bind) ComboBox、Button 和 Command 的方法,以便当 ComboBox 的值更改时,在 Command 上调用 CanExe
在玩具应用程序中,我有一个显示所有帖子标题的“帖子”模板。当您单击每个标题时,我不想直接进入“显示” View ,而是直接内联展开该帖子的其余内容。 我考虑过让 postRoute 重用 postsR
我需要一些使用 Twitter Bootstrap 或其他响应式框架的自定义 Swagger-UI 实现。需要在我的移动设备上使用这样的 UI 测试我的 API,但 swagger-ui 不能很好地扩
我正在做一个项目,我真的在尝试编写面向对象的 JavaScript 代码。我刚刚开始阅读Douglas Crockford's JavaScript: The Good Parts我很快开始意识到用
在 C# 中,我通过执行以下操作来加密文本数据(请注意我正在以 block ( block )的形式加密数据): public string EncryptData(string pu
我正在构建一个社交网站,该网站将向全世界公开 REST API (WCF WebAPI),以便任何开发人员都能够为该网站创建客户端应用程序、将其与其他服务集成等。 我想为 API 实现 Faceboo
我是一名优秀的程序员,十分优秀!