如何用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中 ...
随机推荐
- Java.前端.Layer.open.btn验证无效
今天遇到了一个很可笑的问题,在.Layer弹窗open中设置了多个按钮,只有yes按钮有效,btn2点击后直接关闭弹窗,排查了2个小时后终于解决,就是btn2要return false! var in ...
- Qt Installer Framework翻译(4)
教程:创建安装程序 本教程描述如何为一个小项目创建一个简单的安装程序: 本节描述创建安装程序所必须完成的步骤: 创建一个包文件夹,其中将包含所有配置文件和可安装的包. 创建一个配置文件,其中包含有关如 ...
- 查看jvm内存信息
Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx Runtime.getRuntime().freeMemory(); //当前JVM空闲内存 Run ...
- 如何取消chrome的自动翻译
设置中搜索“翻译” 然后关掉“询问是否翻译非您所用语言的网页”的选项即可 需要翻译的时候在目标网页右键“翻译成中文”即可 用github的时候烦的要死,翻译的贼不准.
- isinstance 和type
推荐使用 isinstance 判断对象类型. isinstance 的用法: 语法: isinstance(object, classinfo) 其中,object 是变量,classinfo 是类 ...
- BZOJ 3691 游行
题目传送门 分析: 没被访问的点要C费用,跑一次路要C费用 把这两个统一一下试试... 那就是每次不标记起点或者终点 那就是路径覆盖了2333 二分图,x 部 i 号点与 y 部 j 号点连 i 到 ...
- 个人第四次作业:Alpha项目测试
个人第四次作业:Alpha项目测试 格式描述 详情 这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience ...
- 在vue中使用jquery
首先默认你已经有了一个vue程序,如果你想在vue中使用jquery,那么请继续阅读. 当然,加入你没有一个vue程序,这里也给出创建一个vue程序的命令.当然,你肯定装了vue-cli,不然你不会点 ...
- RAID磁盘冗余阵列
RAID阵列分类 **一.RAID 0** 1.优点: 充分利用 I/O 总线性能使其带宽翻倍,读/写速度翻倍: 充分利用磁盘空间,利用率为 100%.2.缺点: 不提供数据冗余: 无数据检验,不能保 ...
- systemctl中添加mysql服务
由于mysql的版本更新,许多术语有了新含义,所以需要特别指出,mysqld.service 等价于mysqld vim /usr/lib/systemd/system/mysqld.service ...