如何用Java8 Stream API找到心仪的女朋友
传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量。
而Java8 Stream API 可以极大简化这一操作,代码行数少,且易读。
我们以“找女朋友”为例来看看Java8的Stream API相比传统写法有多香。假设我们定义了一个女朋友类,具有几个关键的指标:姓名,身高,体重,颜值。如下所示:
class Girl {
private String name;
private int height;
private int weight;
private int score;
// 省略get,set及hashCode等方法
}
我们有一批适龄女青年名单,如下:
public static List<Girl> initGirlList(){
List<Girl> result = new ArrayList<>();
result.add(new Girl("赵小花",170,60,6));
result.add(new Girl("钱小花",171,62,7));
result.add(new Girl("孙小花",172,59,8));
// 省略....
return result;
}
心仪女朋友的筛选条件
假设心仪的女朋友是:体重,身高适中,颜值越高越好。本次设置的条件是找出:身高>=162 并且 体重<=53的女孩,然后按颜值排序前三名。
Java7的写法
数据去重
由于数据可能有重复,这会干扰我们的筛选,因此,第一步先去掉重复数据。代码如下:
List<Girl> girlList = initGirlList();// 初始化一批数据
// 数据去重
List<Girl> distinctGirl = new ArrayList<>();
for (Girl g: girlList){
if(!distinctGirl.contains(g)){
distinctGirl.add(g);
}
}
这里new了一个新的distinctGirl来存放去重之后的数据,代码很简单,没啥可说的。
筛选数据
下面我们要去掉不合格的数据,本次筛选条件是身高>=162 并且 体重<=53,代码如下:
// 过滤身高,体重不符合的
List<Girl> girlTemp = new ArrayList<>();
for(Girl g: distinctGirl){
if(g.getHeight() >= 162 && g.getWeight() <= 53){
girlTemp.add(g);
}
}
这里运用上一步中去重之后的distinctGirl,遍历,并将符合条件的放入新的list girlTemp,这里又创建了一个中间list。
数据排序
经过上面啰嗦的两步,我们得到了符合我们要求的数据,现在我们需要根据颜值高低进行排名,代码如下:
Collections.sort(girlTemp, new Comparator<Girl>() {
@Override
public int compare(Girl g1, Girl g2) {
BigDecimal score1 = new BigDecimal(g1.getScore());
BigDecimal score2 = new BigDecimal(g2.getScore());
return score2.subtract(score1).intValue();
}
});
这里使用了Collections工具类的sort方法,传递了一个匿名类,并在其compare方法中实现了排序的逻辑,这依然是传统集合排序的操作。
输出结果
经过上面的几步传统的Java集合操作,我们终于得到了想要的数据。现在我们要输出前三名。
int i = 1;
for (Girl g : girlTemp) {
if(i>=3){
break;
}
System.out.println(g.toString());
}
OK,至此我们的程序输出了筛选的结果。上面的写法,貌似逻辑很清晰,一步步徐徐渐进。是的,这种传统的写法,Java程序员们已经乐呵呵的写了很多年了。
一看这个代码足足有20多行!可是实现的逻辑并没有太复杂啊?过阵子你回头看这个代码的话,你多半忘记了这么一大段代码是干嘛的。如果有注释还好,你大概扫一一眼能帮助你快速理清代码做了啥。如果没有注释,你需要逐行去读完这20多行代码,才能明白其逻辑。
Java8 Stream API的写法
这里我们在回顾一下,我们的目标:从一个girlList中找出:身高>=162 并且 体重<=53的女孩,然后按颜值排序前三名。Java8的代码如下:
List<Girl> girlList = initGirlList();
girlList.stream()
.filter( g -> g.getHeight() >= 162 && g.getWeight() <= 53)
.distinct()
.sorted(Comparator.comparing(Girl::getScore).reversed())
.limit(3)
.forEach( g -> System.out.println(g.toString()));
代码6行!并且即使不了解Stream API,且你第一次看这个代码也能猜出是什么意思,filter-过滤,distinct-去重,sort-排序,limit-限制条数,forEach-遍历,就这么简单。
结语
Java 这么老语言,如今都Java13了,然而,最具影响的版本我认为还是Java8。我上学那会儿,学校用Java6的写法教学。工作之后开始写Java7的try-with-resource、钻石语法等。一直到现在,市面上很多项目都是Java7。有一次有同事给我说他在前公司写Java8被项目经理说了一顿,我问为啥。他说因为项目经理认为写Java7好维护,团队人人都会写Java7,写Java8的人不多……无语凝噎。
如果你还没用上Java8,但愿本文中的小例子已经成功的勾起了你用上Java8的兴致。问卷:你现在使用的版本是多少?
评论下面附了完整源码

推荐阅读
Java8系列- 何用Java8 Stream API进行数据抽取与收集
SpringMVC是怎么工作的,SpringMVC的工作原理
Mybatis Mapper接口是如何找到实现类的-源码分析
小程序云开发:菜鸟也能全栈做产品
CORS详解,CORS原理分析
工作6年,失业19天
Docker & k8s 系列一:快速上手docker
Docker & k8s 系列二:本机k8s环境搭建
Docker & k8s 系列三:在k8s中部署单个服务实例
如何用Java8 Stream API找到心仪的女朋友的更多相关文章
- 何用Java8 Stream API进行数据抽取与收集
上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据 ...
- 使用Java8 Stream API对Map按键或值进行排序
一.什么是Java 8 Stream 使用Java 8 Streams,我们可以按键和按值对映射进行排序.下面是它的工作原理: 将Map或List等集合类对象转换为Stream对象 使用Streams ...
- Fork/Join框架与Java8 Stream API 之并行流的速度比较
Fork/Join 框架有特定的ExecutorService和线程池构成.ExecutorService可以运行任务,并且这个任务会被分解成较小的任务,它们从线程池中被fork(被不同的线程执行)出 ...
- Java8 Stream API
Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String co ...
- JAVA8 Stream API的使用
/** * @auther hhh * @date 2018/12/31 12:48 * @description Stream流:用来处理数组.集合的API * 1.不是数据结构,没有内部存储(只是 ...
- java8 stream api流式编程
java8自带常用的函数式接口 Predicate boolean test(T t) 传入一个参数返回boolean值 Consumer void accept(T t) 传入一个参数,无返回值 F ...
- 1.分类维护-通过Java8 Stream API 获取商品三级分类数据
实体类 @Data @TableName("pms_category") public class CategoryEntity implements Serializable { ...
- java8 Stream API笔记
生成Stream Source的方式 从Collection和数组生成 * Collection.stream() * Collection.parallelStream() * Arrays.str ...
- 【Java8新特性】面试官:谈谈Java8中的Stream API有哪些终止操作?
写在前面 如果你出去面试,面试官问了你关于Java8 Stream API的一些问题,比如:Java8中创建Stream流有哪几种方式?(可以参见:<[Java8新特性]面试官问我:Java8中 ...
随机推荐
- restframework 解析器、渲染器、url控制组件
一.解析器 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己可以处理的数据.本质就是对请求体中的数据进行解析. 1.分类 from rest_framework.parsers impo ...
- kuangbin专题专题十一 网络流 POJ 3436 ACM Computer Factory
题目链接:https://vjudge.net/problem/POJ-3436 Sample input 1 3 4 15 0 0 0 0 1 0 10 0 0 0 0 1 1 30 0 1 2 1 ...
- 如何取消chrome的自动翻译
设置中搜索“翻译” 然后关掉“询问是否翻译非您所用语言的网页”的选项即可 需要翻译的时候在目标网页右键“翻译成中文”即可 用github的时候烦的要死,翻译的贼不准.
- python实例:从excel读取股票代码,爬取股票信息写到代码后面的单元格中
关键词:爬虫.python.request.接口.excel处理 思路: 1.首先准备好excel文档,把股票代码事先编辑进去. 2.脚本读取文档,依次读出股票代码到指定站点发起请求获取股票信息 3. ...
- Java多线程:实现API接口创建线程方式详解
先看例子: /**实现Runnable接口创建线程步骤: * 1.创建一个实现Runnable接口的类 * 2.重写Runnable类中抽象的run()方法 * 3.创建实现类的对象 * 4.声明Th ...
- Linux下的expect
expect简介 expect是一款自动化的脚本解释型的工具. expect基于tcl脚本,expect脚本的运行需要tcl的支持. expect对一些需要交互输入的命令很有帮助,比如ssh ftp ...
- JDK Proxy和CGLIB Proxy
动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...
- ArrayAccess 接口(源码)
The ArrayAccess interface (PHP 5 >= 5.0.0, PHP 7) Introduction Interface to provide accessing obj ...
- 【故障公告】再次遭遇SQL语句执行超时引发网站首页访问故障
非常抱歉,昨天 18:40~19:10 再次遭遇上次遇到的 SQL 语句执行超时引发的网站首页访问故障,由此您带来麻烦,请您谅解. 上次故障详见故障公告,上次排查下来以为是 SQL Server 参数 ...
- [GPU高性能编程CUDA实战].(桑德斯).聂雪军等.扫描版-百度云分享
链接:https://pan.baidu.com/s/1NkkDiyRgmfmhm9d2g_GBKQ 提取码:3usj