首页 > 其他分享 >Stream流处理快速上手最佳实践

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

时间:2023-09-14 16:34:22浏览次数:28  
标签:Collectors Stream stream collect List list 实践 最佳

一 引言

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 转载请注明来源

标签:Collectors,Stream,stream,collect,List,list,实践,最佳
From: https://www.cnblogs.com/Jcloud/p/17688106.html

相关文章

  • 一文了解袋鼠云在实时数据湖上的探索与实践
    近日,袋鼠云大数据引擎专家郝卫亮,为大家带来了《袋鼠云在实时数据湖上的探索与实践》主题分享,帮助大家能了解到什么是实时数据湖、如何进行数据湖选型及数据平台建设数据湖的经验。如今,大规模、高时效、智能化数据处理已是“刚需”,企业需要更强大的数据处理能力,来应对数据查询、数据......
  • 一文了解袋鼠云在实时数据湖上的探索与实践
    近日,袋鼠云大数据引擎专家郝卫亮,为大家带来了《袋鼠云在实时数据湖上的探索与实践》主题分享,帮助大家能了解到什么是实时数据湖、如何进行数据湖选型及数据平台建设数据湖的经验。如今,大规模、高时效、智能化数据处理已是“刚需”,企业需要更强大的数据处理能力,来应对数据查询、......
  • Go之流程控制大全: 细节、示例与最佳实践
    本文深入探讨Go语言中的流程控制语法,包括基本的if-else条件分支、for循环、switch-case多条件分支,以及与特定数据类型相关的流程控制,如for-range循环和type-switch。文章还详细描述了goto、fallthrough等跳转语句的使用方法,通过清晰的代码示例为读者提供了直观的指导。关注微......
  • Java8 Optional用法和最佳实践
    介绍根据Oracle文档,Optional是一个容器对象,可能包含也可能不包含非空值。Java8中引入它是为了解决NullPointerException的问题。本质上,Optional是一个包装类,其中包含对其他对象的引用。在这种情况下,对象只是指向内存位置的指针,它也可以指向任何内容。另一种看待它的方式......
  • 万字详解 Stream 流式编程,写代码也可以很优雅
    一、引言流式编程的概念和作用Java流(Stream)是一连串的元素序列,可以进行各种操作以实现数据的转换和处理。流式编程的概念基于函数式编程的思想,旨在简化代码,提高可读性和可维护性。JavaStream的主要作用有以下几个方面:简化集合操作:使用传统的for循环或迭代器来处理集合数据可......
  • vivo数据中心网络链路质量监测的探索实践
    作者:vivo互联网服务器团队-WangShimin网络质量监测中心是一个用于数据中心网络延迟测量和分析的大型系统。通过部署在服务器上的Agent发起5次ICMPPing以获取端到端之间的网络延迟和丢包率并推送到存储与分析模块进行聚合和分析与存储。控制器负责分发PingList并通过数据中......
  • 《从实践中学习TCP/IP协议》笔记
    2.2网络体系802.3以太网802.11无线网络802.16WiMAX2.4以太网以太网采用附加冲突检测的载波侦听多路访问(CSMA/CD)机制,以太网中所有节点都可以看到在网络中发送的所有信息,以太网是一种广播网络以太网帧结构,由前同步码+帧开始定界符+以太网报头(目的地址+源地址+类型假定IP)+......
  • 学习笔记之Redis消息队列-基于Stream的消息队列
    学习笔记之Redis消息队列-基于Stream的消息队列Stream是Redis5.0引入的一种新数据类型,可以实现一个功能非常完善的消息队列。其实只需要知道写入消息队列的命令和读取消息队列的命令就行了写入消息队列:XADD读取消息队列的方式之一:XREAD在业务开发中,我们可以循环的调用......
  • Stream4Flow
    Aframeworkforthereal-timeIPflowdataanalysisbuiltonApacheSparkStreaming,amoderndistributedstreamprocessingsystem.Thisprojectisnolongermaintained⚠ProjectStream4Flowisnolongermaintainedastheusedframeworksareconstantlyev......
  • uniapp项目实践总结(十五)使用websocket实现简易聊天室
    导语:在一些社交软件中,经常可以看到各种聊天室的界面,接下来就总结一下聊天室的原理个实现方法,最后做一个简易的聊天室,包括登录/登出、加入/离开房间、发送接收聊天消息等功能。目录准备工作原理分析组件实现实战演练服务端搭建案例展示准备工作在pages/index文件夹下......