传统的的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找到心仪的女朋友的更多相关文章

  1. 何用Java8 Stream API进行数据抽取与收集

    上一篇中我们通过一个实例看到了Java8 Stream API 相较于传统的的Java 集合操作的简洁与优势,本篇我们依然借助于一个实际的例子来看看Java8 Stream API 如何抽取及收集数据 ...

  2. 使用Java8 Stream API对Map按键或值进行排序

    一.什么是Java 8 Stream 使用Java 8 Streams,我们可以按键和按值对映射进行排序.下面是它的工作原理: 将Map或List等集合类对象转换为Stream对象 使用Streams ...

  3. Fork/Join框架与Java8 Stream API 之并行流的速度比较

    Fork/Join 框架有特定的ExecutorService和线程池构成.ExecutorService可以运行任务,并且这个任务会被分解成较小的任务,它们从线程池中被fork(被不同的线程执行)出 ...

  4. Java8 Stream API

    Stream是Java8中,操作集合的一个重要特性. 从iteration到Stream操作 当你操作一个集合的时候,你通常的做法是迭代每一个元素,然后处理你想要的事情.举个例子: String co ...

  5. JAVA8 Stream API的使用

    /** * @auther hhh * @date 2018/12/31 12:48 * @description Stream流:用来处理数组.集合的API * 1.不是数据结构,没有内部存储(只是 ...

  6. java8 stream api流式编程

    java8自带常用的函数式接口 Predicate boolean test(T t) 传入一个参数返回boolean值 Consumer void accept(T t) 传入一个参数,无返回值 F ...

  7. 1.分类维护-通过Java8 Stream API 获取商品三级分类数据

    实体类 @Data @TableName("pms_category") public class CategoryEntity implements Serializable { ...

  8. java8 Stream API笔记

    生成Stream Source的方式 从Collection和数组生成 * Collection.stream() * Collection.parallelStream() * Arrays.str ...

  9. 【Java8新特性】面试官:谈谈Java8中的Stream API有哪些终止操作?

    写在前面 如果你出去面试,面试官问了你关于Java8 Stream API的一些问题,比如:Java8中创建Stream流有哪几种方式?(可以参见:<[Java8新特性]面试官问我:Java8中 ...

随机推荐

  1. LeetCode 第三题--无重复字符的最长子串

    1. 题目 2.题目分析与思路 3.思路 1. 题目 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3 ...

  2. excel中为什么不显示单引号

    解决:打两个就可以了!因为:一个单引号表示该单元格为文本属性.

  3. Qt Installer Framework翻译(3-5)

    指定设置选项 设置页面使用户可以指定代理设置或安装附加组件. 用户在简介页面上点击"设置"来指定设置选项. 指定代理设置 默认情况下,安装程序使用系统代理设置.用户可以选择不使用或 ...

  4. .net Core发布至IIS完全手册带各种踩坑

    服务器环境配置 和各位大爷报告一下我的服务器环境 : Windows Server 2012 iis 8 小插曲开始: 运维大哥在昨天给了我一台新的server 0环境开始搭建 . 并且没有安装任何的 ...

  5. 深入理解Java虚拟机:JVM高级特性与最佳实践

    第一部分走近Java第1章走近Java21.1概述21.2Java技术体系31.3Java发展史51.4Java虚拟机发展史91.4.1SunClassicExactVM91.4.2SunHotSpo ...

  6. FluentData -Micro ORM with a fluent API that makes it simple to query a database

    Code samples Create and initialize a DbContextThe connection string on the DbContext class can be in ...

  7. 关于 C#和.net 的 发展

    591. C# 1 的 委托 语法 看起来 似乎 并不 太坏 [2016-04-27 09:00:56]592. C# 2 支持 从 方法 组 到 一个 兼容 委托 类型 的 隐式 转换. [2016 ...

  8. JavaFx图形界面开发

    相关学习教程:http://www.javafxchina.net/blog/docs/ ,makery写的教程:https://code.makery.ch/zh-cn/library/javafx ...

  9. Kotlin Android项目静态检查工具的使用

    Kotlin Android项目静态检查工具的使用 Kotlin Android项目可用的静态检查工具: Android官方的Lint, 第三方的ktlint和detekt. 静态检查工具 静态检查工 ...

  10. 计算机网络基础:TCP和UDP

    UDP(用户数据报协议) 应用场景:一个数据包就能完成数据通信:不需要建立会话和流量控制:多播.广播:是一种不可靠传输.(例如QQ聊天,屏幕广播) UDP协议特点: UDP是无连接的,即发送数据之前不 ...