java8学习之Stream分组与分区详解
Stream应用:
继续举例来操练Stream,对于下面这两个集合:

需求是:将这两个集合组合起来,形成对各自人员打招呼的结果,输出的结果如:
"Hi zhangsan"、"Hi lisi"、"Hi wangwu"、"Hi zhangliu";
"Hello zhangsan"、"Hello lisi"、"Hello wangwu"、"Hello zhangliu";
"你好 zhangsan"、"你好 lisi"、"你好 wangwu"、"你好 zhangliu";
那如何实现呢?其思路应该是:首先从list1中取出1个元素,然后再跟list2集合中的每个元素进行拼接操作,而list1对应一个stream,list2也对应一个stream,等于要操作两个Stream,那肯定得要用到flatMap()将其打平成一个Stream嘛,下面具体来实现一下:

好好体会一下flatMap()的用法。
Stream分组:
之前【http://www.cnblogs.com/webor2006/p/8302401.html】也提到过Stream跟咱们数据库中的Sql很类似,都是属于描述性的语言,其中对于sql语句中可以用group by对数据进行分组,而在Stream中也有分组的功能,所以接下来举例来使用一下,以从学生中进行分组为例,首先新建一个学生类:
public class Student {
/* 姓名 */
private String name;
/* 分数 */
private int score;
/* 年龄 */
private int age;
public Student(String name, int score, int age) {
this.name = name;
this.score = score;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接下来构造学生集合:

接下来按姓名进行分组,对于sql语句而言比较简单,如下语句就可以达到要求:
select * from student group by name;
而对于这个需求如果采用传统的作法应该是按如下步骤进行:
1、循环列表;
2、取出学生的名字;
3、本地会一个Map<String, List<Student>>的本地map进行数据存放,然后每次遍历元素时会检测map中是否存在该名字,不存在则直接添加到map中;存在则将map中的List对象取出来,然后将该Student对象添加到该List当中;
4、返回该map对象。
可见传统方式是何等的麻烦,下面采用函数式的方式来实现,看下是何等的简单:

而这次分组就得再次用到这个Collectors,它是一个辅助类,之前还使用过求最大值,最小值之类的,那这次分组得用哪个方法呢?

可以看到在它里面有三个重载跟分组相关的方法,其名字跟sql语句中的基本上差不多,这里会用到第一个重载方式,接收一个Function参数的,简单看一下方法的描述:

那具体怎么传参数呢?其实可以使用方法引用的方式来传,如下:

编译运行:
{lisi=[com.study.jdk8.stream.Student@b4c966a], zhangsan=[com.study.jdk8.stream.Student@2f4d3709, com.study.jdk8.stream.Student@4e50df2e], wangwu=[com.study.jdk8.stream.Student@1d81eb93]}
可见采用Stream方式实现分组是何等的简单。
接下来对分数进行分组,依葫芦画瓢呗:

其输出:
{80=[com.study.jdk8.stream.Student@6e8cf4c6], 100=[com.study.jdk8.stream.Student@12edcd21], 90=[com.study.jdk8.stream.Student@34c45dca, com.study.jdk8.stream.Student@52cc8049]}
接下来现来更改需求,这时还是根据名字进行分组,但是输出变了,输出变成名字及它里面分组的个数了,其对应SQL语句类似于它:
select name, count(*) from student group by name;
那这时得用到另外一个重载的groupingby()方法啦,如下:

其方法原型定义如下:

那具体怎么做呢?如下:

其中看一下counting()方法:

编译运行:

接下来需求进一步升级,这时以名字进行分组之后求一下各组学生成绩的平均值并打印出来,其思路跟上面求个数的类似,如下:

其中averagingDouble()方法看一眼:

下面编译运行:

Stream分区:
对于分组可以称为"group by",那对于分区呢?可以叫"partition by",其实分区是分组的一种特例,其结果只有两组,怎么理解,比如:从学生集合中对90分及以上的以及90分以下的学生进行分区,就像考驾照上机操作时,90分及以上的为及格,而以下的则为不及格,这就是所谓的分区,那如何做呢?

这次就不用groupingBy()方法了,而是采用partitioningBy()了,有两个方法重载,这里用第一个,如下:

编译运行:
{false=[com.study.jdk8.stream.Student@2f4d3709], true=[com.study.jdk8.stream.Student@4e50df2e, com.study.jdk8.stream.Student@1d81eb93, com.study.jdk8.stream.Student@7291c18f]}
是不是再一次体现出了Java8中的Stream是有多强大了,接下来还会不断进行探究,彻底去掌握它~
java8学习之Stream分组与分区详解的更多相关文章
- java8学习之Stream介绍与操作方式详解
关于默认方法[default method]的思考: 在上一次[http://www.cnblogs.com/webor2006/p/8259057.html]中对接口的默认方法进行了学习,那在Jav ...
- Java 8系列之Stream的基本语法详解
本文转至:https://blog.csdn.net/io_field/article/details/54971761 Stream系列: Java 8系列之Stream的基本语法详解 Java 8 ...
- oracle表分区详解
原文来自:http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html oracle表分区详解 从以下几个方面来整理关于分区表的概念及 ...
- ASP.NET MVC 5 学习教程:生成的代码详解
原文 ASP.NET MVC 5 学习教程:生成的代码详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- 基于集合成工控机Ubuntu系统安装分区详解
基于集合成工控机Ubuntu系统安装分区详解 硬件描述:双核的CPU,128G的固态硬盘 软件描述:使用Ubuntu12.04系统,内核3.8.0-29版本,QT4.8.1版本 1.新建分区表 /de ...
- SQL Server表分区详解
原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆 ...
- linux下磁盘分区详解 图文(fdisk;mkfs)
linux分区不同于windows,linux下硬盘设备名为(IDE硬盘为hdx(x为从a-d)因为IDE硬盘最多四个,SCSI,SATA,USB硬盘为sdx(x为a-z)),硬盘主分区最多为4个,不 ...
- IP地址和子网划分学习笔记之《IP地址详解》
2018-05-03 18:47:37 在学习IP地址和子网划分前,必须对进制计数有一定了解,尤其是二进制和十进制之间的相互转换,对于我们掌握IP地址和子网的划分非常有帮助,可参看如下目录详文. ...
- OpenCV学习C++接口 Mat像素遍历详解
OpenCV学习C++接口 Mat像素遍历详解
随机推荐
- Web jsp开发学习——dbcp jsp连接MySQL出现中文乱码解决
开发过程中,通过dbcp.properties连接MySQL数据库,向数据库中插入中文字符时,出现乱码情况. 通过查阅资料,发现出现乱码的原因:MySQL数据库使用的是UTF-8编码,而dbcp.pr ...
- C#字符串内插-$
1.字符串内插 $特殊字符将字符串文本标识未内插字符串,可能包含内插表达式的字符串文本. 将内插字符串解析为结果字符串,带有内插表达式的项会替换为表达式结果的字符串表示形式. 在C#6级更高版本语言中 ...
- Golang中用interface{}接收任何参数与强转
函数的传值中,interface{}是可以传任意参数的,就像java的object那样.下面上我第一次想当然写的 ** 错误 **代码 package main func main() { Any(2 ...
- 安卓渗透测试工具——Drozer(安装和使用)
移动端渗透测试工具相比丰富的web端真的是少之又少,最近在做app的安全测试,用到了drozer,drozer的安装过程真的是太心酸了,中间报错了有6次才成功安装.. 一.环境准备 首先准备以下环境: ...
- 40G传输技术浅析
采用40G传输技术给运营商带来的好处 - 同样的带宽,更低的硬件成本.由于目前的光电器件工艺已臻于成熟,质量更为可靠,使40G的商用具有了必要的前提.同样是40G容量,器件的数量大致只有4个10G光接 ...
- webdriervAPI(键盘事件)
from selenium import webdriver from selenium.webdriver.common.keys import Keys #导入键盘操作事件 driver ...
- python学习笔记四 (运算符重载和命名空间、类)
从以上代码中应该了解到: obj.attribute 查找的顺序: 从对象,类组成的树中,从下到上,从左到右到查找最近到attribute属性值,因为rec中存在name的属性,所以x.name可以 ...
- Oracle中分析函数
1. row_number() over(PARTITION BY ...ORDER BY...)--在求第一名成绩的时候,不能用,因为如果有两个并列第一,只会返回一个 rank() over(PAR ...
- [AGC040C] Neither AB nor BA
Description 一个长度为 n 的字符串是好的当且仅当它由 'A', 'B', 'C' 组成,且可以通过若干次删除除了"AB"和"BA"的连续子串变为空 ...
- CF 1133C Balanced Team
题目链接:http://codeforces.com/problemset/problem/1133/C 题目分析 (个人感受:我看错了题目,硬是写了近一个小时!) 这个题目要求一个最长的序列,使得这 ...