大数据项目2(Java8聚合操作)
前言:为很好的理解这些方法,你需要熟悉java8特性Lambda和方法引用的使用
一:简介
我们用集合的目的,往往不是简单的仅仅把数据保存哪里。而是要检索(遍历)或者去计算或统计....操作集合里面的数据。现假设我有一个实体对象Person如下,用于测试集合操作
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
Person(String nameArg, LocalDate birthdayArg, Sex genderArg, String emailArg) {
name = nameArg;
birthday = birthdayArg;
gender = genderArg;
emailAddress = emailArg;
}
public int getAge() {
return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears();
}
public void printPerson() {
System.out.println(name + ", " + this.getAge());
}
public Sex getGender() {
return gender;
}
public String getName() {
return name;
}
public String getEmailAddress() {
return emailAddress;
}
public LocalDate getBirthday() {
return birthday;
}
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}
public static List<Person> createRoster() {
List<Person> roster = new ArrayList<>();
roster.add(new Person("Fred", IsoChronology.INSTANCE.date(1980, 6, 20), Person.Sex.MALE, "fred@example.com"));
roster.add(new Person("Jane", IsoChronology.INSTANCE.date(1990, 7, 15), Person.Sex.FEMALE, "jane@example.com"));
roster.add(
new Person("George", IsoChronology.INSTANCE.date(1991, 8, 13), Person.Sex.MALE, "george@example.com"));
roster.add(new Person("Bob", IsoChronology.INSTANCE.date(2000, 9, 12), Person.Sex.MALE, "bob@example.com"));
return roster;
}
@Override
public String toString() {
return "Person [name=" + name + ", birthday=" + birthday + ", gender=" + gender + ", emailAddress="
+ emailAddress + "]";
}
}
1.1 管道和流
NOTE: 管道是一个有序的聚合操作(A pipeline is a sequence of aggregate operations)
举例一:打印集合中所有性别为男性的名字
@Test
public void test1() {
roster.stream().filter(e -> e.getGender() == Person.Sex.MALE).forEach(e -> System.out.println(e.getName()));
}
当然你也可以用 for-each 循环做到这一点
分析:管道中包含了那些组件
一个数据源,即一个集合 roster
0个或多个中间操作,本例中只有一个.filter过滤集合中的男性。
一个终止操作,即forEach遍历并打印姓名,无返回值。
举例二:计算平均数,即计算集合中男性的平局年龄
@Test
public void test() {
double average = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).mapToInt(Person::getAge)
.average().getAsDouble();
System.out.println(average);
}
聚合过程 filter-->mapToInt-->average()-->getAsDouble
二:还原操作
Note:The JDK contains many terminal operations (such as average, sum, min, max, and count) that return one value by combining the contents of a stream. These operations are called reduction operations.
还原操作:个人理解还原操作即一种终止某种过程或状态的操作,并转换成另外一种状态。在这里即是对流的终止操作,并转化为另一种状态(另一种状态即Double或Int....包括引用类型)
这里主要介绍两种 Stream.reduce和Stream.collect方法。
2.1:Stream.reduce 计算总和
方法一:通过sum() 聚合 roster.stream().mapToInt(Person::getAge).sum();
方法二:即通过Stream.reduce
Integer totalAgeReduce = roster.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
NOTE: 0 可以改为任意Int数据,其作用就是在原总和的基础上加上0
2.2 :Stream.collect方法 还原成其他类型
举例一:计算平均数,还原成指定类型Averager
public class Averager implements IntConsumer {
private int total = 0;
private int count = 0;
public double average() {
return count > 0 ? ((double) total) / count : 0;
}
public double getTotal() {
return total;
}
@Override
public void accept(int i) {
total += i;
count++;
}
public void combine(Averager other) {
total += other.total;
count += other.count;
}
}
测试:
@Test
public void test3() {
SupplierImpl impl = new SupplierImpl();
Averager averageCollect = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).map(Person::getAge)
.collect(Averager::new, Averager::accept, Averager::combine);
System.out.println("Average age of male members: " + averageCollect.average()); Averager averageCollect2 = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE).map(Person::getAge)
.collect(impl, Averager::accept, Averager::combine);
System.out.println("Average age of male members22: " + averageCollect2.average());
}
The collect operation in this example takes three arguments:
supplier: The supplier is a factory function; it constructs new instances. For thecollectoperation, it creates instances of the result container. In this example, it is a new instance of theAveragerclass.accumulator: The accumulator function incorporates a stream element into a result container. In this example, it modifies theAveragerresult container by incrementing thecountvariable by one and adding to thetotalmember variable the value of the stream element, which is an integer representing the age of a male member.combiner: The combiner function takes two result containers and merges their contents. In this example, it modifies anAveragerresult container by incrementing thecountvariable by thecountmember variable of the otherAveragerinstance and adding to thetotalmember variable the value of the otherAveragerinstance'stotalmember variable
举例二:Stream.collect方法 还原成List<String>
@Test
public void test5() {
List<String> namesOfMaleMembersCollect = roster.stream().filter(p -> p.getGender() == Person.Sex.MALE)
.map(p -> p.getName()).collect(Collectors.toList());
namesOfMaleMembersCollect.forEach(System.out::print);
System.out.println();
namesOfMaleMembersCollect.add("1234");
namesOfMaleMembersCollect.forEach(System.out::print);
}
举例三:Stream.collect方法 还原成Map<Object,List<Object>,
@Test
public void test6() {
Map<Sex, List<Person>> byGender = roster.stream().collect(Collectors.groupingBy(Person::getGender));
Set<Sex> keySet = byGender.keySet();
for (Sex sex : keySet) {
List<Person> list = byGender.get(sex);
System.out.println("sex = " + sex);
list.forEach(System.out::print);
System.out.println();
}
}
使用场景:对源数据进行分组
举例四:Stream.collect方法 还原成Map<Object,List>,
@Test
public void test7() {
Map<Person.Sex, List<String>> namesByGender = roster.stream().collect(
Collectors.groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toList())));
Set<Sex> keySet = namesByGender.keySet();
for (Sex sex : keySet) {
List<String> list = namesByGender.get(sex);
System.out.println("sex = " + sex);
list.forEach(System.out::print);
System.out.println();
}
Map<Person.Sex, List<String>> namesByGender2 = roster.stream().collect(Collectors.groupingBy((p) -> {
return p.getGender();
}, Collectors.mapping(Person::getName, Collectors.toList())));
Set<Sex> keySet2 = namesByGender2.keySet();
for (Sex sex : keySet2) {
List<String> list = namesByGender2.get(sex);
System.out.println("sex = " + sex);
list.forEach(System.out::print);
System.out.println();
}
}
举例五:Stream.collect方法,分组并求和
@Test
public void test8() {
Map<Person.Sex, Integer> totalAgeByGender = roster.stream().collect(
Collectors.groupingBy(Person::getGender, Collectors.reducing(0, Person::getAge, Integer::sum)));
Set<Sex> keySet2 = totalAgeByGender.keySet();
for (Sex sex : keySet2) {
Integer integer = totalAgeByGender.get(sex);
System.out.println("sex = " + sex);
System.out.println("年龄sum = " + integer); }
}
举例六:Stream.collect方法,分组并计算平均数
@Test
public void test9() {
Map<Person.Sex, Double> averageAgeByGender = roster.stream()
.collect(Collectors.groupingBy(Person::getGender, Collectors.averagingInt(Person::getAge)));
Set<Sex> keySet2 = averageAgeByGender.keySet();
for (Sex sex : keySet2) {
Double double1 = averageAgeByGender.get(sex);
System.out.println("sex = " + sex);
System.out.println("年龄avg = " + double1);
}
}
三 并行操作(Parallelism)
llll
大数据项目2(Java8聚合操作)的更多相关文章
- 大数据项目实践:基于hadoop+spark+mongodb+mysql+c#开发医院临床知识库系统
一.前言 从20世纪90年代数字化医院概念提出到至今的20多年时间,数字化医院(Digital Hospital)在国内各大医院飞速的普及推广发展,并取得骄人成绩.不但有数字化医院管理信息系统(HIS ...
- 大数据项目测试<二>项目的测试工作
大数据的测试工作: 1.模块的单独测试 2.模块间的联调测试 3.系统的性能测试:内存泄露.磁盘占用.计算效率 4.数据验证(核心) 下面对各个模块的测试工作进行单独讲解. 0. 功能测试 1. 性能 ...
- 大数据项目之_15_电信客服分析平台_03&04_数据分析
3.3.数据分析3.3.1.Mysql 表结构设计3.3.2.需求:按照不同的维度统计通话3.3.3.环境准备3.3.4.编写代码:数据分析3.3.5.运行测试3.3.6.bug 解决 3.3.数据分 ...
- 大数据项目相关技术栈(Hadoop周边技术)
J2EE 框架Spring 开发框架 + SSH or SSM Lucene 索引和查询IKAnalyzer 分词Webmagic 爬虫 ETL工具:KettleSqoop 结构化数据库-hadoop ...
- Mysql备份系列(3)--innobackupex备份mysql大数据(全量+增量)操作记录
在日常的linux运维工作中,大数据量备份与还原,始终是个难点.关于mysql的备份和恢复,比较传统的是用mysqldump工具,今天这里推荐另一个备份工具innobackupex.innobacku ...
- 如何在IDEA里给大数据项目导入该项目的相关源码(博主推荐)(类似eclipse里同一个workspace下单个子项目存在)(图文详解)
不多说,直接上干货! 如果在一个界面里,可以是单个项目 注意:本文是以gradle项目的方式来做的! 如何在IDEA里正确导入从Github上下载的Gradle项目(含相关源码)(博主推荐)(图文详解 ...
- 大数据项目(MTDAP)随想
Spark MLlib进行example测试的时候,总是编译不通过,报少包<Spark MLlib NoClassDefFoundError: org/apache/spark/ml/param ...
- 大数据项目之_15_电信客服分析平台_01&02_项目背景+项目架构+项目实现+数据生产+数据采集/消费(存储)
一.项目背景二.项目架构三.项目实现3.1.数据生产3.1.1.数据结构3.1.2.编写代码3.1.3.打包测试3.2.数据采集/消费(存储)3.2.1.数据采集:采集实时产生的数据到 kafka 集 ...
- 华为大数据项目fusionInsight
项目简述:基于开源Hadoop2.0架构的集群网络,进行海量数据的分布式计算.由于Hadoop集群规模不断扩大,而搭建一个同等规模的测试集群需要一笔昂贵的开销.目前有100台左右物料,期望预测计算节点 ...
随机推荐
- js数组合并以及对象的遍历
这是很基础的知识,but,对于一只未系统学习过js,只略懂搬砖的跨界狗,还是经常犯错: 场景:移动端上拉加载更多. 初始数组合并后来请求的数组. 使用concat方法,不过要主要: 使用concat, ...
- go modules 学习
go modules 学习 tags:golang 安装 只需要golang的版本是1.11及之后的,这个模块就内置好了 环境变量 (1) 配置GoLang的GOROOT (2) 可以不配置GoLan ...
- 使用Docker搭建maven私服 及常规使用方法
安装-登录-配置 下载镜像 docker pull sonatype/nexus3 运行 docker run -d -p 9998:8081 --name nexus --restart=alway ...
- 微信小程序使用 ECharts 实现数据可视化
微信小程序使用 ECharts 显示图表 首先创建微信小程序 这里就不再赘述 下载 GitHub 上的 ecomfe/echarts-for-weixin 下载后解压,打开文件夹,里面的 ec-can ...
- day 39 盒模型 display 浮动
一.盒模型 属性: width:内容的宽度 height:内容的高度 padding:内边距 内容到边框的距离 border:边框 margin:外边距 另一个边到另一个边的距离 盒模型的计算: 总结 ...
- 手把手教你优雅的编写第一个SpringMVC程序
可能之前写的文章走进SpringMVC世界,从SpringMVC入门到SpringMVC架构中的第一个springMVC入门程序讲解的不是那么优雅.细致.精巧,因此特地写这篇稍微优雅.细致.精巧一些的 ...
- Crontab爬虫定时执行
- win到linux的编码问题
从windows到linux的文件可能存在编码问题时,这是因为,Linux和Windows文本文件的行结束标志不同.在Linux中,文本文件用"\n"表示回车换行,而Windows ...
- 洛谷P2085——最小函数值
题目描述 有n个函数,分别为\(F_1,F_2,...,F_n\).定义\(F_i(x)=A_i*x^2+B_i*x+C_i (x∈N*)\).给定这些\(A_i.B_i和C_i\),请求出所有函数的 ...
- 【游记】CSP J/S 2019 游记
J 组 \(2:30\)开始, \(2:13\)还在酒店的我看了看手表...飞奔考场. T1 数字游戏 秒切. 下午某中学某大佬说可用线性基(%) T2 公交换乘 用单调队列思想,秒切. T3 纪念品 ...