【cfeng work】WorkProj中Stream流的应用详细介绍

news/2025/3/24 7:30:08/

WorkProj

内容管理

  • Stream
    • 中间操作 (流不会关闭)
      • filter(x -> x boolean表达式) 筛选返回值为true的
      • distinct() 去重
      • limit(X) 返回前x个元素
      • skip(x) 跳过流中元素
      • map(x操作) 对每一个元素映射操作
      • mapToInt() 将对象流转为数值流 Integer --> int
      • flatMap(x操作) 将一个流中每一个值转为流 【针对对象为集合/array】合并集合
      • sorted(Comparator.comparing(字段)) 将stream中元素排序
    • 终端操作 (关闭流), 返回值
      • allMatch(x -> x boolean表达式) 当stream中所有元素满足条件返回true
      • anyMatch(x -> x boolean表达式) 当stream中一个元素满足就返回true
      • noneMatch(x -> x boolean表达式) 全部不满足返回true
      • count() 统计流中元素个数
      • findFirst() 返回流中第一个元素
      • findAny() 返回流中随机一个元素
      • max/min () 返回流中的最大最小值
      • sum() 求和
      • foreach() 遍历
      • reduce 将流中的元素组合 ⭐ 可替代max、min、sum等
      • collect 返回集合 collect策略有很多 ---> ⭐ 可执行sum、average...等
        • 类型归纳 --- 转为集合容器 toXXX
        • joining 将元素用某规则连接起来
        • collectingAndThen 先对结果进行归纳,之后再进行Function函数处理结果
        • groupingBy 按照条件对结果分组
        • counting 对收集的结果求和
        • mapping(mapper, downSream) 在Collect中进行隐射
        • maxBy(comparator)/minBy
        • summingInt/Double/Long(元素 -- 可用Lambda)
        • summarizingDouble/Int/Long⭐ 统计量: 包括总数 和 max/min 平均值
        • reducing ⭐ (T, T) -> T 元素两两比较淘汰一个(一轮轮reduce)


本文introduce 对于Stream的使用


在关系型数据库中处理数据还是很easy的,使用group by , order by等关键字可以方便查出各种数据

但是很多场景下数据不是在数据库中处理, 而是直接拎到内存中处理, 这个时候Stream就可以发挥巨大作用【相较于传统的for遍历】

比如java的dynamicSqlBuilder, 动态SQL查询出动态数据库表中的数据【所有都是动态的】, 这里的返回值就是List<Map<String, Object>>

要对List<Map<String,Object>>进行处理, 通过Stream的方式就是最快的

流stream是支持数据处理操作的源生成的元素序列, 源可以是数组、文件、集合、函数; Stream不是集合,不是数据结构,主要目的就是计算

Stream

Stream创建方式一共有5种, 集合、数组、of值、文件、函数iterator无限流

  • 最常见的就是通过集合Collection生成
Stream stream = distinctMap.values().stream

除此之外,也可以通过数组Arrays.sttream(数组)、 Stream.of(值1, 值2…)、Files.lines(文件)、 Stream.iterator(xxx)无限流 | Stream.generator(xxx)无限流

流Stream的操作分为两种

  • 中间操作: 一个流后面可以跟随0或者多个中间操作,打开流做出某种程度的映射, 操作是惰性化的,没有真正开始流的遍历, 常见的map、filter都是
  • 终端操作: 一个流只能有一个终端操作,进行流的遍历,操作执行后,流就关闭了,不能再操作,因此一个流只能遍历一次,如collect、count

中间操作 (流不会关闭)

中间操作可以为 0 ~ 多个, 一定程度的映射和操作

比如List list = Arrays.asList(1,1,2,3,4,5,6);

filter(x -> x boolean表达式) 筛选返回值为true的

list.stream().filter(item -> item > 3)//这里的item代表的就是流中的每一个元素,可以使用Lambda表达式
//4,5,6    

distinct() 去重

list.stream().distinct()//结果1,2,3,4,5,6    

limit(X) 返回前x个元素

这个和数据库limit类似

list.stream().limit(3)//1,1,2    

skip(x) 跳过流中元素

和limit相反,跳过前X个元素

list.stream().skip(3)//3,4,5,6    

map(x操作) 对每一个元素映射操作

操作位置可以使用Lambda或者函数引用

list.stream().map(x -> x + 1)//2,2,3,4,5,6,7

mapToInt() 将对象流转为数值流 Integer --> int

flatMap(x操作) 将一个流中每一个值转为流 【针对对象为集合/array】合并集合

这个和Map的不同主要就是针对List<List<>>的情况, 一层流只能得到List, 要想直接得到最内层对象,就只能flatMap, 会将所有的List全转化为流

List<List《Stream>> strList = [[“java,python”], [“cfeng”,“cshen”]]

strList.stream().flatMap(item -> item.Stream())

sorted(Comparator.comparing(字段)) 将stream中元素排序

这个sorted中可以给出字段,就是按照默认的顺序排序,加上.reversed()就可以倒序,当然也可以使用Lambda表达式进行定制的排序

list.stream.sorted(Comparator.comparing(Book:: getPublishTime).reversed())

终端操作 (关闭流), 返回值

终端操作只能一个, 会对流进行遍历(和requestBody一样,只能一次性)

allMatch(x -> x boolean表达式) 当stream中所有元素满足条件返回true

if(list.stream.allMatch(item -> item > 3))//这里false,因为1,1,2,3几个元素不满足    

anyMatch(x -> x boolean表达式) 当stream中一个元素满足就返回true

if(list.stream.anyMatch(item -> item > 5))//true,因为6这个元素满足    

noneMatch(x -> x boolean表达式) 全部不满足返回true

if(list.stream.noneMatch(item -> item > 5))//false,因为6这个元素满足    

count() 统计流中元素个数

list.stream().count()
//个数7  

findFirst() 返回流中第一个元素

list.stream().findFirst()
//1

findAny() 返回流中随机一个元素

list.stream().findAny()
//4 , 随机的    

max/min () 返回流中的最大最小值

list.stream().min(Integer::CompareTo)list.stream().min()//1

sum() 求和

list.stream().sum() //可以用lambda统计元素, 比如str.length求和//1 + 1 + 2 + 3 + 4 + 5 + 6    

foreach() 遍历

list.stream().foreach(System::println);
//1 /n 1 .....

reduce 将流中的元素组合 ⭐ 可替代max、min、sum等

(T,T) -> T, 不断reduce

collect 返回集合 collect策略有很多 —> ⭐ 可执行sum、average…等

最常见的collect就是Collectors.toList()策略, 就是将流转为一个List

类型归纳 — 转为集合容器 toXXX

Collectors.toList();
Collectors.toMap();
Collectors.toSet();
Collectors.toCollection();//含参构造,转化为new的容器
Collectors.toConcurrentMap();

分别将流转为List、Map、Set、Collection、 ConcurrentMap

joining 将元素用某规则连接起来

连接符号可以是delimiter连接符; 或者delimiter连接符、prefix开始符,suffix结束符; 除此之外,还可以空参,代表delimiter为空格

Collectors.joining();  // 以空格连接Collectors.joining("-");  //以-连接Collectors.joining("【",",","】"); //以【x, y, z.....】

collectingAndThen 先对结果进行归纳,之后再进行Function函数处理结果

结果操作就是将collect结果再执行

List<String> list = Arrays.asList("cfeng", "java", "数字大屏");
String str = list.stream().collect(Collectors.collectingAndThen(Collectors.joining(",","[","]"), s -> s + "你好")); System.out.println(str);

groupingBy 按照条件对结果分组

和SQL的group by类似,内存分组可以减少压力

比如

// 按照字符串长度进行分组    符合条件的元素将组成一个 List 映射到以条件长度为key 的 Map<Integer, List<String>> 中
servers.stream.collect(Collectors.groupingBy(String::length))

为了保证线程安全,可以采用安全的Map

 Supplier<Map<Integer, Set<String>>> mapSupplier = () -> Collections.synchronizedMap(new HashMap<>());Map<Integer, Set<String>> collect = servers.stream.collect(Collectors.groupingBy(String::length, mapSupplier, Collectors.toSet()));

或者可以直接使用groupingByConcurrent

counting 对收集的结果求和

list.stream().count() 效果一样
list.sream().collect(Collectors.counting())

mapping(mapper, downSream) 在Collect中进行隐射

List<String> names = students.stream().collect(Collectors.mapping(Student::getName, Collectors.toList()));

maxBy(comparator)/minBy

大小元素的操作,和list.stream.max终端操作一样

list.stream().collect(Collectors.minBy(Comparator.comparingInt(String.length)))  //字符串中比较按照长度比较list.stream().min(Comparator.comparingInt(String.length))

summingInt/Double/Long(元素 – 可用Lambda)

累加操作,和sum()终端操作一样

list.stream().collect(Collectors.summingInt(s -> s.length)))  //字符串中比较按照长度比较list.stream().min(Comparator.comparingInt(String.length))

summarizingDouble/Int/Long⭐ 统计量: 包括总数 和 max/min 平均值

summarizing对应的就是统计量,会将总数、总和、max、min、avg等统计量提取出来放到IntSummaryStatisics(Double、 Long) 等统计对象中

IntSummaryStatistics  statistics = list.stream().collect(Collectors.summarizingInt(s -> s.length)));

需要的数据再从对象中直接取出即可

reducing ⭐ (T, T) -> T 元素两两比较淘汰一个(一轮轮reduce)

这个方法对用的终端操作也就是reduce

其参数为BinaryOperator< T》 , 给两个相同类型的量,返回一个同类型的结果, (T, T) -> T, 默认实现为maxBy和minBy, 也就是返回最大/小值, 元素两两比较根据给定的策略淘汰一个, 随着迭代的进行,元素reduce

下面是一个例子

//统计城市个子最高的人Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);  //子当以比较器为比较Person的身高Map<String, Optional<Person>> tallestByCity = people.stream().collect(Collectors.groupingBy(Person::getCity, Collectors.reducing(BinaryOperator.maxBy(byHeight))));

http://www.ppmy.cn/news/153606.html

相关文章

Spring Cloud Alibaba - Nacos源码分析

目录 一、源码 1、为什么要分析源码 2、看源码的方法 二、Nacos服务注册与发现源码剖析 1、Nacos核心功能点 2、Nacos服务端/客户端原理 2.1、nacos-example 2.2、Nacos-Client测试类 3、项目中实例客户端注册 一、源码 1、为什么要分析源码 1. 提升技术功底&#x…

UsonixR8系列--无线掌上超声技术指标

UR8 掌上超声系列具备下述特性。 扫描方式&#xff1a;电子扫描 成像模式&#xff1a; B 发射频率&#xff1a;凸阵 2.5MHz~4.0MHz 线阵 6MHz~8MHz 测 量&#xff1a;距离、面积、周长 探测深度&#xff1a;线阵&#xff1a; 20mm~60mm&#xff0c; 凸阵&#xff1a; 80mm~220m…

电脑鸿蒙系统怎么连接无线网络,三星笔记本电脑怎么连接无线网wifi

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 三星笔记本电脑连接无线网wifi的方法是&#xff1a; 1、打开桌面开始菜单&#xff0c;点击控制面板。 2、点击网络和Internet。 3、接着点击网络和共享中心下的查看网络状态。 4、再…

掌上研究生显示服务器未连接,掌上生活老是提示服务器通讯异常是怎么回?

2014-01-11 为什么掌上生活在手机上使用不了 您好&#xff0c;若您是使用我行的手机掌上生活&#xff0c;根据您的提示&#xff0c;可能是由于网络通讯不稳定&#xff0c;请按以下步骤设置后&#xff0c;再次尝试一下。1。手机时间日期设置问题&#xff0c;请检查手机的时间和日…

台式计算机怎样能搜无线连接,台式机怎样能够连入wifi呢

优质回答 回答者&#xff1a;wjaie 2019-01-03 台式机需要外置无线网卡才可以连接wifi&#xff0c;一次安装永久使用&#xff0c;目前市面价格20元-100元不等。 连接方式 1、买到如图所示的这种USB无线网卡&#xff0c;免驱动版的 2、无线网卡直接插到电脑USB插口&#xff0c;开…

android版 暴风影音,Android版暴风影音 掌上的3D影院

如今安卓手机的屏幕越来越大了,性能越来越好,用来看电影、看电视是个不错的选择。当你在公交车上或者躺在床上,可以拿出手机悠闲地看着自己喜爱的电影或节目,快乐地度过原本无聊的时间。如果你觉得不够爽,小编建议你使用可以观看3D视频的APP—暴风影音。 近期,暴风科技旗…

无线掌上B超USONIX-R6开发全流程

欢迎光临Usonix博客-分享超声技术 USonix无线掌上B超基本特性 USonix无线掌上B超 欢迎访问USonix博客&#xff0c;记录分享超声技术。USONIX-R6硬件实物如下&#xff1a; USONIX-R6 Windows软件界面如下&#xff1a; 基本特性 USonix-R6具备如下特性&#xff1a; 图像模…

WIFI原理,WIFI6各代介绍 2020-11-23

Wi-Fi&#xff08;发音&#xff1a; /ˈwaɪfaɪ/[1][2][3]&#xff0c;“wireless fidelity”的缩写&#xff09;&#xff0c;又称“无线热点”或“无线网络”&#xff0c;是Wi-Fi联盟的商标&#xff0c;一个基于IEEE 802.11标准的无线局域网技术。“Wi-Fi”常被写成“WiFi”或…