Java8 - 定制归一化收集器(reducing)得到自定义结果集
reducing简介
reducing 是一个收集器(操作),从字面意义上可以理解为“减少操作”:输入多个元素,在一定的操作后,元素减少。
reducing 有多个重载方法,其中一个方法如下:
public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op)
以上方法,JDK对其的描述是:
Returns a Collector which performs a reduction of its input elements under a specified BinaryOperator. The result is described as an Optional. (返回一个收集器,该收集器在指定的二进制操作符下执行其输入元素的减少。结果被描述为可选的 <T>。)
reducing的应用
reducing 是一个非常有用的收集器,可以用在多层流、下游数据分组或分区等场合。
下面是一个例子:
给定一组 Person 对象,每个 Person 都有 city(所在城市)和 height(身高)属性,编写一个程序,统计出每个不同的城市最大、最小身高值。
import java.util.*;
import java.util.function.BinaryOperator;import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;/*** ReducingDemo** @author Zebe*/
public class ReducingDemo {/*** 运行入口** @param args 运行参数*/public static void main(String[] args) {List<Person> personList = getPersonList(1000000);functionStyle(personList);normalStyle(personList);}/*** 函数式编程风格(3行处理代码)* @param personList Person 列表*/private static void functionStyle(List<Person> personList) {long start = System.currentTimeMillis();// 创建一个比较器,取名为 byHeight (通过高度来比较)Comparator<Person> byHeight = Comparator.comparingInt(Person::getHeight);// 创建一个归一收集器Map<City, Optional<Person>> tallestByCity = personList.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));long usedTime = System.currentTimeMillis() - start;printResult("函数式编程风格", personList.size(), usedTime, tallestByCity);}/*** 普通编程风格(20行处理代码)* @param personList Person 列表*/private static void normalStyle(List<Person> personList) {long start = System.currentTimeMillis();// 创建一个结果集Map<City, Optional<Person>> tallestByCity = new HashMap<>();// 第一步:找出所有的不同城市Set<City> cityList = new HashSet<>();for (Person person : personList) {if (!cityList.contains(person.getCity())) {cityList.add(person.getCity());}}// 第二部,遍历所有城市,遍历所有人找出每个城市的最大身高for (City city : cityList) {int maxHeight = 0;Person tempPerson = null;for (Person person : personList) {if (person.getCity().equals(city)) {if (person.getHeight() > maxHeight) {maxHeight = person.getHeight();tempPerson = person;}}}tallestByCity.put(city, Optional.ofNullable(tempPerson));}long usedTime = System.currentTimeMillis() - start;printResult("普通编程风格", personList.size(), usedTime, tallestByCity);}/*** 获取Person列表* @param numbers 要获取的数量* @return 返回指定数量的 Person 列表*/private static List<Person> getPersonList(int numbers) {// 创建城市final City cityChengDu = new City("成都");final City cityNewYork = new City("纽约");List<Person> people = new ArrayList<>();// 创建指定数量的Person,并指定不同的城市和相对固定的身高值for (int i = 0; i < numbers; i++) {if (i % 2 == 0) {// 成都最大身高185people.add(new Person(cityChengDu, 185));} else if (i % 3 == 0) {people.add(new Person(cityChengDu, 170));} else if (i % 5 == 0) {// 成都最小身高160people.add(new Person(cityChengDu, 160));} else if (i % 7 == 0) {// 纽约最大身高200people.add(new Person(cityNewYork, 200));} else if (i % 9 == 0) {people.add(new Person(cityNewYork, 185));} else if (i % 11 == 0) {// 纽约最小身高165people.add(new Person(cityNewYork, 165));} else {// 默认添加纽约最小身高165people.add(new Person(cityNewYork, 165));}}return people;}/*** 输出结果* @param styleName 风格名称* @param totalPerson 总人数* @param usedTime 计算耗时* @param tallestByCity 统计好最大身高的城市分组MAP*/private static void printResult(String styleName, long totalPerson, long usedTime, Map<City, Optional<Person>> tallestByCity) {System.out.println("\n" + styleName + ":计算 " + totalPerson + " 个人所在不同城市最大身高的结果如下:(耗时 " + usedTime + " ms)");tallestByCity.forEach((city, person) -> {person.ifPresent(p -> System.out.println(city.getName() + " -> " + p.getHeight()));});}}
Person类
/*** Person** @author Zebe*/
public class Person {/*** 所在城市*/private City city;/*** 身高*/private int height;/*** 构造器* @param city 所在城市* @param height 身高*/public Person(City city, int height) {this.city = city;this.height = height;}public City getCity() {return city;}public void setCity(City city) {this.city = city;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}
}
City类
/*** City** @author Zebe*/
public class City {/*** 城市名*/private String name;/*** 构造器* @param name 城市名*/public City(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
注:以上代码如果要计算最小值、平均值,将 maxBy 换成 minBy 就可以了。
输出结果
程序输出结果如下:
函数式编程风格:计算 1000000 个人所在不同城市最大身高的结果如下:(耗时 149 ms)
成都 -> 185
纽约 -> 200普通编程风格:计算 1000000 个人所在不同城市最大身高的结果如下:(耗时 82 ms)
成都 -> 185
纽约 -> 200
可以看出,函数式编程的效率不一定会比普通编程效率更高,甚至相对要慢一点,但是,函数式编程的好处在于:
- 把参数作为一个函数,而不是值,实现了只有在需要的时候才计算(惰性求值)。
- 使用 lambda 表达式能够简化程序表达的含义,使程序更简洁明了。
本文原文地址:https://blog.csdn.net/zebe1989/article/details/82855511
Java8 - 定制归一化收集器(reducing)得到自定义结果集相关推荐
- java8默认内存收集器_使用正确的垃圾收集器将Java内存使用量降至最低
java8默认内存收集器 大小对于软件至关重要. 很明显,与大的整体方法相比,在微服务体系结构中使用小片段具有更多优势. 最新的Java版本的Jigsaw有助于分解旧应用程序或从头开始构建新的云原生应 ...
- java8自定义收集器_使用自定义收集器进行Java 8分组?
我有以下课程. class Person { String name; LocalDate birthday; Sex gender; String emailAddress; public int ...
- 流集数据收集器最新消息
最新消息 3.10.0 中的新增功能 数据收集器版本 3.10.0 包括以下新功能和增强功能: 起源 此版本包括以下新源: Groovy 脚本 - 运行 Groovy 脚本以创建数据收集器记录. 脚本 ...
- Java虚拟机(三)--------GC算法和收集器
如何判断对象可以被回收 堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的 对象) 引用计数法 给对象添加一个引用计数器,每当有一个地方引用,计数器 ...
- GC算法与GC收集器
Java相比于C++这样语言,除了跨平台的特性外,最突出的特点就是垃圾回收机制.C++的开发人员还需要手动分配和回收内存,但JVM直接承担起了垃圾回收的重任,开发人员可以专注于业务开发,不需要再去关心 ...
- (七)JVM成神路之GC分代篇:分代GC器、CMS收集器及YoungGC、FullGC日志剖析
引言 在<GC基础篇>中曾谈到过分代以及分区回收的概念,但基础篇更多的是建立在GC的一些算法理论上进行高谈阔论,而本篇则重点会对于分代收集器的实现进行全面详解,其中会涵盖串行收集器.并行收 ...
- Java8 Stream 自定义收集器Collector
在之前的例子中,我们都是使用Collectors的静态方法提供的CollectorImpl,为接口Collector<T, A, R>的一个实现类,为了自定义我们自己的Collector, ...
- 矩阵累积相乘 java_累积:轻松自定义Java收集器
矩阵累积相乘 java Accumulative是针对Collector<T, A, R>的中间累积类型A提出的接口Collector<T, A, R>以使定义自定义Java ...
- 累积:轻松自定义Java收集器
Accumulative是针对Collector<T, A, R>的中间累积类型A提出的接口Collector<T, A, R>以使定义自定义Java Collector更加容 ...
- Stream流与Lambda表达式(四) 自定义收集器
一.自定义SetCustomCollector收集器 package com.java.design.Stream.CustomCollector;import java.util.*; import ...
最新文章
- Java工具类之:包装类
- 从R-CNN到YOLO,2020 图像目标检测算法综述
- 笔记 | 深入理解深度学习语义分割
- Java 编程下的同步代码块
- 下列数据类型中python不支持的是_ 下列选项中 ,Python 不支持的数据类型有 ( ) 。_学小易找答案...
- 倒计时 | 7.24 阿里云 Serverless Developer Meetup 杭州站报名火热进行中!
- linux下SD卡烧录程序
- 为什么有人说开车时,最能看出一个人的情商和潜力?
- Linux基础(2)-基础命令和bash的基础特性(1)
- VueRouter基础知识记录1
- 给Activity设置背景色
- 锐捷校园网环境下使用虚拟机上网
- 2022爱分析・汽车行业数字化实践报告
- 《模拟电子技术》–童诗白
- cad导出jpg格式什么像素最清晰
- 背景色及色彩搭配方案推荐
- 安全体系建设-基础安全
- Windows10官网原版系统下载地址汇总
- 我叫MT4怎么在电脑上玩?我叫MT4手游安卓模拟器电脑版操作教程
- 雨林木风:dll文件下载网站
热门文章
- linux安装redis 完整步骤 主从结构 和 cluster 集群搭建
- matlab求解微分方程ode23
- 怎样恢复误删计算机管理员,win10管理员账号误删只有普通权限怎么恢复
- randn函数 python_Python numpy matrix randn()用法及代码示例
- python安装requirement.txt的扩展包
- mysql 月初 月末_月初 月末 sql 语句(日期所在月的第一天,最后一天)
- GetLastError()函数
- 梯度的旋度为零证明_旋度的逆运算
- hyperledger fabric 2.3.3 环境搭建教程
- 《炬丰科技-半导体工艺》化学添加剂对KOH 溶液中Si表面反应性的影响