Stream流处理快速上手最佳实践

2023-11-04

一 引言

JAVA1.8得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。

二 常用方法介绍

2.1 获取Stream流

所有的 Collection 集合都可以通过 stream 默认方法获取流;

java.util.Collection 接口中加入了default方法 stream 用来获取流,所以其所有实现类均可获取流。

ArrayList<XyBug> xyBugList = new ArrayList();
Stream<XyBug> stream = xyBugList.stream();


Stream 接口的静态方法 of 可以获取数组对应的流。

//String
Stream<String> stream = Stream.of("aa", "bb", "cc");
//数组
String[] arr = {"aa", "bb", "cc"};
Stream<String> stream7 = Stream.of(arr);
Integer[] arr2 = {11, 22, 33};
Stream<Integer> stream8 = Stream.of(arr2);
//对象
XyBug xyBug1 = new XyBug();
XyBug xyBug2 = new XyBug();
XyBug xyBug3 = new XyBug();
Stream<XyBug> bugStream = Stream.of(xyBug1, xyBug2, xyBug3);



2.2 Stream 数据处理常用方法

forEach方法

该方法接收一个 Consumer 接口函数,会将每一个流元素交给该函数进行处理

List<String> list = new ArrayList<>();
Collections.addAll(list, "str1", "str2", "str3", "str4", "str5", "str6");
list.stream().forEach((String s) -> {
  System.out.println(s);
  });
//简写
list.stream().forEach(s -> System.out.println(s));


s代表list中的每一个元素,流式处理依次遍历每个元素

->后的代码为每个元素处理逻辑

count方法

count 方法来统计其中的元素个数,返回值为long类型

long count = list.stream().count();


distinct方法

对流中的数据进行去重操作,普通类型可直接去重

//将22、33重复数据去除
Stream.of(22, 33, 22, 11, 33).distinct().collect(Collectors.toList());


自定义类型是根据对象的hashCode和equals来去除重复元素的

XyBug实体类中加@Data注解,hashCode和equals会别重写,在使用distinct方法时判断去重

ArrayList bugList = JSON.parseObject(bugs, ArrayList.class);
ArrayList<XyBug> xyBugList = new ArrayList();
List collect = (List) bugList.stream().distinct().collect(Collectors.toList());


通过distinct()方法去重,去重后的数据通过collect(Collectors.toList())组成新6的list

limit方法

方法可以对流进行截取,只取用前n个,参数是一个long型,如果集合当前长度大于参数则进行截取。否则不进行操作

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5", "6");
List<String> collect = list.stream().limit(3).collect(Collectors.toList());


将前3个String对象截取,组成新的list

skip方法

如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流,如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5", "6");
List<String> collect = list.stream().skip(3).collect(Collectors.toList());


跳过前3个String对象,后三个组成新的list

filter方法

filter用于过滤数据,返回符合过滤条件的数据,可以通过 filter 方法将一个流转换成另一个子集流,该接口接收一个 Predicate 函数式接口参数(可以是一个Lambda或方法引用)作为筛选条件

List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "22", "3", "4", "55", "6");
//filter方法中写入筛选条件,将过滤后的数据组成新的list
list.stream().filter(s -> s.length() == 2).collect(Collectors.toList());


通过该条语句s -> s.length() == 2,筛选出22、55

map方法

将流中的元素映射到另一个流中,可以将当前流中的T类型数据转换为另一种R类型的流

List<PersonCrDto> laputaCrDtos = queryListLaputaByBeginEndTime(begin, end);
//将list中的PersonCrDto对象的userName属性取到,收集成set集合
laputaCrDtos.stream().map(PersonCrDto::getUserName).collect(Collectors.toSet())


将list中的每个对象的userName数据拿到,组成Set集合

stream分组

List<XyBug> list = new ArrayList<>();
Map<String, List<XyBug>> collect = list.stream().collect(Collectors.groupingBy(XyBug::getBugType));


根据bug类型进行分组,分组后会组成map,key是组名,value是组下的数据

stream排序

sort(),默认正序排列,加入reversed()方法后倒叙排列

List<XyBug> list = new ArrayList<>();
//根据createTime正序排列
List<XyBug> collect = list.stream().sorted(Comparator.comparing(XyBug::getCreateTime)).collect(Collectors.toList());
//根据createTime倒叙排列
List<XyBug> collect = list.stream().sorted(Comparator.comparing(XyBug::getCreateTime).reversed()).collect(Collectors.toList());



collect方法

将处理后数据收集为list,collect(Collectors.toList())

将处理后数据收集为set,collect(Collectors.toSet())

根据某个字段值将数据分组map,collect(Collectors.groupingBy(o -> o.value())))

三 实践举例

需求:将bug数据通过orgTierName分组,存储到map中

未使用Stream,需要使用for循环并且进行各种判断,代码行数较多

HashMap<String, List<XyBug>> map = new HashMap<>();
for (XyBug one : bugList){
    if(one.getOrgTierName() != null){
        if(map.get(one.getOrgTierName()) == null){
            List<XyBug> list = new ArrayList();
            list.add(one);
            map.put(one.getOrgTierName(),list);
        }else {
            map.get(one.getOrgTierName()).add(one);
        }
    }
}


使用Stream,一行代码搞定,直观并高效

collectDeptBugMap = bugList.stream().filter(o -> o.getOrgTierName() != null).collect(Collectors.groupingBy(o -> o.getOrgTierName()));


四 总结

Stream是对集合(Collection)对象功能的增强,能对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作,提高编程效率、简洁性和程序可读性。本文通过简单举例,希望帮助读者快速上手使用流处理,Stream流处理功能非常强全,更多方法请参考API文档。

作者:京东物流 杨靖平

来源:京东云开发者社区  自猿其说Tech 转载请注明来源

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Stream流处理快速上手最佳实践 的相关文章

随机推荐

  • jQuery的筛选器

    jQuery的筛选器 用在jQuery选择的元素集合的后面 都是方法 为了对已经选择出来的元素进行二次筛选 筛选器 1 first gt 筛选集合里面的第一个元素 2 last gt 筛选集合里面的最后一个元素 3 eq n gt 筛选集合
  • openGL之API学习(五十六)低模、高模的区别以及各自的使用领域

    高模是高细节高精度的3D模型 高模看上去十分逼真细节非常丰富模型的面数也相当的高 低模是游戏里的说法 可以理解为游戏所使用的模型 高模有很多作用可以用于电影制作 广告等等 在游戏里高模主要是为了烘焙NormalMap 并且运用在游戏低模型上
  • Antd a-tree 树形控件,选中的节点高亮。

    实现最简单的树展示列表 效果图 template中
  • javaWeb

    1 基本概念 Web开发 静态网页 提供给所有人看的数据始终不会发生变化 动态网页 提供给所有人看的数据始终会发生变化 每个人在不同的时间 不同的地点看到的信息各不相同 在java中 动态Web资源开发的技术统称为javaWeb web应用
  • 脑电信号EEG分类基础入门(1)机器学习编程环境搭建

    网上大多数资料都是基于python语言的 我的编程环境和工程都是python 但也会用matlab来可视化理解 用到的安装包和代码资料已经整理好了 https download csdn net download fzf1996 21484
  • Linux学习笔记:用fdisk工具分区,swap分区的管理

    1 什么是MBR 什么是分割表 MBR master boot record 即硬盘的主引导记录 分割表 partition table 即硬盘的分区表 在系统关机时 硬盘内的磁盘上的磁头会回到整个磁盘的第一个扇区 当再次启动系统时 磁头会
  • ccwow服务器维护,牧师 - 军团再临 - 178魔兽世界

    牧师职业大厅 军团再临资料片中最大的改动便是神器和职业大厅了 如同德拉诺版本的要塞系统一样 7 0的职业大厅便像是一个强化版的要塞 不过在这里你不再是一个人 相同职业的玩家都会和你在一起来共同探索破碎群岛对抗燃烧军团 那让我们走进虚空之光神
  • calico固定podip

    实现方法 利用calico组件的两个kubernetes注解 1 gt cni projectcalico org ipAddrs 2 gt cni projectcalico org ipv4pools 场景1 单个pod固定ip 利用c
  • HttpClient release connection 该放手的时候必须放手

    Apache commons 系列的HttpClient 相信大家都用过 选择它而非JDK 的java net HttpURLConnection 是为了使用HttpClient 封装的几个实用的功能 目前使用最多的版本还是httpclie
  • 腾讯云2022年双11云服务器配置及报价表汇总

    活动直达 点此进入腾讯云2022年双11活动主会场 腾讯云2022年双11活动的既有轻量应用服务器又有云服务器 购买资格分为个人企业同享和企业用户专享 因此 价格表可分为个人企业同享轻量应用服务器 个人企业同享云服务器 企业专享轻量应用服务
  • 618来袭!我用Python脚本实现了淘宝定时自动秒杀,小白也能轻松搞定!

    准备工作 我们需要把秒杀的商品加入购物车 因为脚本点击的是全选 所以不需要的商品要移出购物车 展示篇幅有限 淘宝秒杀程序的完整源代码已经打包好了 需要的朋友可以扫码加v 我分享给你 过程分析 1 打开某宝网站 pq webdriver Ch
  • 基于Fisco的测压工具使用笔记

    基本过程就是这样了 因为当初写的时候是用OneNote写的 复制过来是图片形式 然后主要的坑就是官方的源码有错误 官方也给了修改意见 根据 修改意见 修改源码 修改完我还碰到一个坑 不知道为什么这个位置缺少文件 移动到这个文件下添加solc
  • 【LeetCode】Day211-不用加减乘除做加法

    题目 剑指 Offer 65 不用加减乘除做加法 中等 题解 不能用加减乘除的题 要考虑位运算 设两数字的二进制形式a b s a b a i 代表a的二进制的第i位 则分为以下四种情况 a i b i 无进位和n i 进位c i 1 0
  • 字符串的总结(atoi和itoa函数的实现)

    目录 一 常见的字符串函数 strlen strcpy strcat strcmp 二 关于atoi函数的实现 三 关于itoa函数的实现 一 常见字符串的函数 strlen strcpy strcat strcmp 1 strlen 求字
  • 在网址上输入www.xxx.com到返回界面给用户发生了什么?

    在网址上输入www xxx com到返回界面给用户发生了什么 DNS域名解析 https blog csdn net m0 37812513 article details 78775629 gt tcp三次握手建立连接 https blo
  • Shiro 如何使用注解式进行授权操作呢?

    转自 Shiro 如何使用注解式进行授权操作呢 下文笔者讲述Shiro进行注解式授权操作的方法分享 如下所示 Shiro注解授权 常使用以下注解字段 如 RequiresRoles RequiresPermissions RequiresA
  • 关闭TCP中135、139、445、593、1025 等端口的操作方法 (转)(记录下)

    操作要领 封闭端口 杜绝网络病毒对这些端口的访问权 以保障计算机安全 减少病毒对上网速度的影响 近日发现有些人感染了新的网络蠕虫病毒 该病毒使用冲击波病毒专杀工具无法杀除 请各位尽快升级计算机上的杀毒软件病毒库 在断开计算机网络连接的情况下
  • AndeSight头文件缺失错误

    使用AndeSight开发山景Demo遇到的问题 路径别带中文名字 一个都不要 其实主要就是一个 当我导入demo之后 编译时遇到问题 缺失 h文件 各种缺失 那么这里我们也可以一个个导入 但是很难受 这里实际上只要在baseSDK建立工程
  • 西门子PLC入门-PLC介绍

    PLC全名 可编程逻辑控制器 Programmable Logic Controller 一种具有微处理器的用于自动化控制的数字运算控制器 可以将控制指令随时载入内存进行储存与执行 PLC由CPU 指令及数据内存 输入 输出接口 电源 数字
  • Stream流处理快速上手最佳实践

    一 引言 JAVA1 8得益于Lambda所带来的函数式编程 引入了一个全新的Stream流概念Stream流式思想类似于工厂车间的 生产流水线 Stream流不是一种数据结构 不保存数据 而是对数据进行加工处理 Stream可以看作是流水