java8 List的Stream流操作 (实用篇 三)
目录
java8 List的Stream流操作 (实用篇 三)
初始数据
1、Stream过滤:
过滤-常用方法
1.1 筛选单元素--年龄等于18
1.2 筛选单元素--年龄大于18
1.3 筛选范围--年龄大于18 and 年龄小于40
1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex==男
1.5 多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合
2、Stream去重(集合去重和按元素去重)
去重-常用方法(关键字distinct、concat和利用set、map)
2.1 关键字distinct去重
2.2 关键字concat合并和distinct 去重
2.3 用set集合去重
2.4 用map去重--以某个元素去重
3、Stream拼接(joining)
拼接-常用方法
3.1 集合内某个字段拼接
3.2 对象内的指定元素map拼接、返回集合
3.3 对象内的指定元素map拼接、再全部拼接
4、Stream分组即组装成map(groupingBy、toMap)
分组-常用方法
4.1 groupingBy-通过年龄分组
4.2 根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)
4.3 toMap-通过userId分组(key重复会报错)
4.4 toMap-通过age分组、取前面的值
4.5 toMap-通过age分组、取后面的值
4.6 toMap-通过男女分组、并且累加age
5、Stream排序:
排序-常用方法
5.1 compareTo 关键字
5.2 Comparator.comparing() 关键方法
5.2.1 排序通常和过滤一起使用、如果元素为空会报错
5.2.2 多个元素排序方法
5.3 自定义排序
6、Stream统计(count、sum、max、min、average)
统计-常用方法
6.1 count-获取user集合中年龄大于18岁的人数
6.2 sum-获取user集合中所有人的年纪的总和
6.3 max-获取user集合中所有人年纪最大的人
6.4 min-获取user集合中所有人年纪最小的人
6.5 average-获取user集合中所有人的年纪的平均值
7、Stream分页(skip、limit)
分页-常用方法
7.1 skip:跳过前n个数据 、limit:获取前n个数据
java8 List的Stream流操作 (实用篇 三)
实际开发的时候想不起来Stream的一些常用方法、去找却很不方便、所以我准备再学一篇实用或者叫常用的stream相关方法的文章。学习整理也是方便查看
结合 java8 List的Stream流操作 (常用篇 一)_java list.stream-CSDN博客
java8 List的Stream流操作 (特别篇 二) toMap_java list tomap-CSDN博客
和实际开发中的需求、按开发使用率排
初始数据
List<User> userList = Lists.newArrayList();userList.add(new User(1,"天一","男",16,true));userList.add(new User(2,"空二","女",19,true));userList.add(new User(3,"张三","男",18,true));userList.add(new User(4,"李四","女",38,true));userList.add(new User(5,"王五","男",18,true));userList.add(new User(6,"王六","男",18,true));userList.add(new User(7,"王七","男",18,true));userList.add(new User(7,"王七","男",18,true));userList.add(new User(8,"王七","男",null,true));
1、Stream过滤:
过滤是我们基本必用的 不管是过滤null值还是按条件过滤都是最常用的。
过滤-常用方法
1.1 筛选单元素--年龄等于18
//筛选单元素--年龄等于18
List<User> filterAgeEqual = userList.stream().filter(user -> user.getAge() == 18).collect(Collectors.toList());
1.2 筛选单元素--年龄大于18
//筛选单元素--年龄大于18
List<User> filterAgeRange = userList.stream().filter(user -> user.getAge() > 18).collect(Collectors.toList());
1.3 筛选范围--年龄大于18 and 年龄小于40
//筛选范围--年龄大于18 and 年龄小于40
List<User> filterAgeRange2 = userList.stream().filter(user -> user.getAge() > 18 && user.getAge() < 40).collect(Collectors.toList());
1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex==男
//多条件筛选--年龄大于18 or 年龄小于40 and sex==男
List<User> filterAgeRange3 = userList.stream().filter(user -> user.getAge() > 18 || user.getAge() < 40 && "男".equals(user.getSex())).collect(Collectors.toList());
1.5 多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合
//多条件筛选--年龄大于18 or 年龄小于40 and sex==男 返回姓名(name)集合
List<String> nameList = userList.stream().filter(user -> (user.getAge() > 18 || user.getAge() < 40) && "男".equals(user.getSex())).map(User::getUserName).collect(Collectors.toList());
2、Stream去重(集合去重和按元素去重)
去重-常用方法(关键字distinct、concat和利用set、map)
2.1 关键字distinct去重
集合内的对象去重--结果是有序的
List<User> distinctList = userList.stream().distinct().collect(Collectors.toList());
2.2 关键字concat合并和distinct 去重
concat:合并两个流 distinct:去重
//concat:合并两个流 distinct:去重
List<User> concatAnddistinctList = Stream.concat(userList.stream(), userList.stream()).distinct().collect(Collectors.toList());
2.3 用set集合去重
集合内的对象去重--结果乱序
//集合内的对象去重--结果乱序
Set<User> setDistinct = userList.stream().collect(Collectors.toSet());
2.4 用map去重--以某个元素去重
以某个元素去重--用map集合 (v1, v2) -> v1 使用v1是表示保留age(年龄)第一次出现的对象、如果使用v2是保留age(年龄)最后一次出现的对象
List<User> mapDistinct = userList.stream().collect(Collectors.collectingAndThen(Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v1),map -> new ArrayList<>(map.values())));
3、Stream拼接(joining)
拼接-常用方法
3.1 集合内某个字段拼接
姓名以,拼接
//姓名以,拼接
String userNameList = userList.stream().map(User::getUserName).collect(Collectors.joining(","));
3.2 对象内的指定元素map拼接、返回集合
每个对象都以 userId-userName-age 拼接、然后返回String集合
//每个对象都以 userId-userName-age 拼接、然后返回String集合
List<String> strList = userList.stream().map((User user) -> user.getUserId() + "-" + user.getUserName() + "-" + user.getAge()).collect(Collectors.toList());
3.3 对象内的指定元素map拼接、再全部拼接
每个对象都以 userId-userName-age 拼接、再以 , 拼接返回字符串
//每个对象都以 userId-userName-age 拼接、再以 , 拼接返回字符串
String userIdAndAgeNameAndList = userList.stream().map((User user) -> user.getUserId() + "-" + user.getUserName() + "-" + user.getAge()).collect(Collectors.joining(","));
4、Stream分组即组装成map(groupingBy、toMap)
分组-常用方法
4.1 groupingBy-通过年龄分组
//groupingBy-通过年龄分组
Map<Integer, List<User>> userGroupingByMap = userList.stream().collect(Collectors.groupingBy(User::getAge));userGroupingByMap.forEach((k, v) -> {System.out.println(k + ":" + v);});
4.2 根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)
//根据userId组装list对象,对应id的对象的某个属性成组(这里用的userName)
Map<Integer,List<String>> mp6 = userList.stream().collect(Collectors.groupingBy(User::getUserId, Collectors.mapping(User::getUserName, Collectors.toList())));
4.3 toMap-通过userId分组(key重复会报错)
//toMap-通过userId分组(key重复会报错)
Map<Integer, User> userToMap = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getUserId, Function.identity()));
4.4 toMap-通过age分组、取前面的值
//toMap-通过age分组、取前面的值
Map<Integer, User> userToMap2 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v1));
4.5 toMap-通过age分组、取后面的值
//toMap-通过age分组、取后面的值
Map<Integer, User> userToMap3 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getAge, Function.identity(), (v1, v2) -> v2));
4.6 toMap-通过男女分组、并且累加age
//toMap-通过男女分组、并且累加age
Map<String, Integer> userToMap4 = userList.stream().filter(user -> user.getAge() != null).collect(Collectors.toMap(User::getSex, User::getAge, (v1, v2) -> v1 + v2));
userToMap4.forEach((k, v) -> {System.out.println(k + ":" + v);
});
5、Stream排序:
开发中有很多都是组装的集合、而要求返回的集合是有序的 (使用率不高的原因是数据库查询支持排序)、
排序-常用方法
单元素排序方法
5.1 compareTo 关键字
(o1, o2) -> o1.getUserId().compareTo(o2.getUserId()) 升序 (o1, o2) -> o2.getUserId().compareTo(o1.getUserId()) 降序
通过指定的userId字段排序
//升序 只写sorted()默认是升序、 我是为了演示才写完整的、开发中可以直接写sorted()
List<User> sortedCompareTo = userList.stream().sorted((o1, o2) -> o1.getUserId().compareTo(o2.getUserId())).collect(Collectors.toList());//降序
List<User> sortedReversed= userList.stream().sorted((o1, o2) -> o2.getUserId().compareTo(o1.getUserId())).collect(Collectors.toList());
5.2 Comparator.comparing() 关键方法
默认升序 加reversed()为降序
//默认升序
List<User> sortedComparator = userList.stream().sorted(Comparator.comparing(User::getUserId)).collect(Collectors.toList());//reversed()为降序
List<User> sortedComparatorReversed = userList.stream().sorted(Comparator.comparing(User::getUserId).reversed()).collect(Collectors.toList());
5.2.1 排序通常和过滤一起使用、如果元素为空会报错
//排序通常和过滤一起使用、如果元素为空会报错
List<User> sortedFilter = userList.stream().filter(user -> user.getAge() != null).sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
5.2.2 多个元素排序方法
排序通常和过滤一起使用、 先用age排序、年龄相同再用userId排序(默认是升序)
//排序通常和过滤一起使用、 先用age排序、年龄相同再用userId排序(默认是升序)
Stream<User> sortedComparators = userList.stream().filter(user -> user.getAge() != null).sorted(Comparator.comparing(User::getAge).thenComparing(User::getUserId));
排序通常和过滤一起使用、 先用age排序升序、年龄相同再用userId排序降序
//排序通常和过滤一起使用、 先用age排序升序、年龄相同再用userId排序降序
Stream<User> sortedComparatorReverseds = userList.stream().filter(user -> user.getAge()!=null).sorted(Comparator.comparing(User::getAge).thenComparing(User::getUserId).reversed());
5.3 自定义排序
先按年龄再按userId自定义排序(降序)
//先按年龄再按userId自定义排序(降序)
List<User> sortedCustom = userList.stream().sorted((u1, u2) -> {if (Objects.equals(u1.getAge(), u2.getAge())) {return u2.getAge() - u1.getAge();} else {return u2.getUserId() - u1.getUserId();}
}).collect(Collectors.toList());
6、Stream统计(count、sum、max、min、average)
统计-常用方法
6.1 count-获取user集合中年龄大于18岁的人数
//count-获取user集合中年龄大于18岁的人数
Long count = userList.stream().filter(user->user.getAge() > 18).count();
System.out.println("user集合中年龄大于18岁的人数:"+count);
6.2 sum-获取user集合中所有人的年纪的总和
//sum-获取user集合中所有人的年纪的总和
Long summingLong = userList.stream().map(User::getAge).collect(Collectors.summingLong(Integer::longValue));
System.out.println("user集合中所有人的年纪的总和:"+summingLong);
6.3 max-获取user集合中所有人年纪最大的人
//max-获取user集合中所有人年纪最大的人
Optional<User> max = userList.stream().max(Comparator.comparing(User::getAge));
System.out.println("user集合中年纪最大的人是:"+max.get().getUserName());
6.4 min-获取user集合中所有人年纪最小的人
//min-获取user集合中所有人年纪最小的人
Optional<User> min = userList.stream().min(Comparator.comparing(User::getAge));
System.out.println("user集合中年纪最小的人是:"+min.get().getUserName());
6.5 average-获取user集合中所有人的年纪的平均值
//average-获取user集合中所有人的年纪的平均值
Double average = userList.stream().map(User::getAge).collect(Collectors.averagingDouble(Integer::doubleValue));
System.out.println("user集合中所有人的年纪的平均值:"+ average);
7、Stream分页(skip、limit)
分页-常用方法
7.1 skip:跳过前n个数据 、limit:获取前n个数据
//skip:跳过前n个数据 、limit:获取前n个数据
List<User> skipAndLimit = userList.stream().skip(1).limit(2).collect(Collectors.toList());
if(!CollectionUtils.isEmpty(skipAndLimit)){skipAndLimit.forEach(System.out::println);
}
相关文章:
java8 List的Stream流操作 (实用篇 三)
目录 java8 List的Stream流操作 (实用篇 三) 初始数据 1、Stream过滤: 过滤-常用方法 1.1 筛选单元素--年龄等于18 1.2 筛选单元素--年龄大于18 1.3 筛选范围--年龄大于18 and 年龄小于40 1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex男 1.5 多条件筛…...
机器学习python实践——数据“相关性“的一些补充性个人思考
在上一篇“数据白化”的文章中,说到了数据“相关性”的概念,但是在统计学中,不仅存在“相关性”还存在“独立性”等等,所以,本文主要对数据“相关性”进行一些补充。当然,如果这篇文章还能入得了各位“看官…...
MySQL——触发器(trigger)基本结构
1、修改分隔符符号 delimiter $$ $$可以修改 2、创建触发器函数名称 create trigger 函数名 3、什么样在操作触发,操作哪个表 after :……之后触发 before :……之后触发 insert :……之后触发 update :……之后触…...
数字孪生定义及应用介绍
数字孪生定义及应用介绍 1 数字孪生(Digital Twin, DT)概述1.1 定义1.2 功能1.3 使用场景1.4 数字孪生三步走1.4.1 数字模型1.4.2 数字影子1.4.3 数字孪生 数字孪生地球平台Earth-2 参考 1 数字孪生(Digital Twin, DT)概述 数字孪…...
数据赋能(122)——体系:数据清洗——技术方法、主要工具
技术方法 数据清洗标准模型是将数据输入到数据清洗处理器,通过一系列步骤“清理”数据,然后以期望的格式输出清理过的数据。数据清洗从数据的准确性、完整性、一致性、惟一性、适时性、有效性几个方面来处理数据的丢失值、越界值、不一致代码、重复数据…...
【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——中
1. 某学校对入学的新生进行性格问卷调查(没有心理学家的参与),根据学生对问题的回答,把学生的性格分成了8个类别。请说明该数据挖掘任务是属于分类任务还是聚类任务?为什么?并利用该例说明聚类分析和分类分析的异同点。 解答: (a)该数据…...
2024年注册安全工程师报名常见问题汇总!
注册安全工程师报名 24年注册安全工程师报名已正式拉开序幕,报名时间为6月18日—7月10日,考试时间为10月26日—10月27日。 目前经有12个地区公布了2024年注册安全工程师报名时间: 注册安全工程师报名信息完善 根据注安报名系统提示&am…...
JRebel-JVMTI [FATAL] Couldn‘t write to C:\Users\中文用户名-完美解决
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 热部署下载参考博客解决第一步第二步第三步:第四步: 热部署下载 下载后启动报错:JRebel-JVMTI [FATAL] Couldn’t write to C:\…...
STM32基于DMA数据转运和AD多通道
文章目录 1. DMA数据转运 1.1 初始化DMA步骤 1.2 DMA的库函数 1.3 设置当前数据寄存器 1.4 DMA获取当前数据寄存器 2. DMA数据转运 2.1 DMA.C 2.2 DMA.H 2.3 MAIN.C 3. DMAAD多通道 3.1 AD.C 3.2 AD.H 3.3 MAIN.C 1. DMA数据转运 对于DMA的详细解析可以看下面这篇…...
安卓应用开发——Android Studio中通过id进行约束布局
在Android开发中,布局通常使用XML文件来描述,而约束(如相对位置、大小等)可以通过多种方式实现,但直接使用ID进行约束并不直接对应于Android的传统布局系统(如LinearLayout、RelativeLayout等)。…...
Elasticsearch过滤器(filter):原理及使用
Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…...
Docker配置与使用详解
一、引言 随着云计算和微服务的兴起,Docker作为一种轻量级的容器化技术,越来越受到开发者和运维人员的青睐。Docker通过容器化的方式,将应用程序及其依赖项打包成一个可移植的镜像,从而实现了应用程序的快速部署和扩展。本文将详…...
触控MCU芯片(1):英飞凌PSoC第6代第7代
前言: 说到触摸MCU芯片,这个历史也是很久了,比如日常经常接触到的洗衣机、电冰箱、小家电,隔着一层玻璃,轻轻一按就能识别按键,感觉比过去纯机械式的按键更高级更美观,不仅白电,现在很多汽车也都在进行触摸按键的改版,不再使用笨重的机械按键,比如空调调温按键、档位…...
git pull报错:unable to pull from remote repository due to conflicting tag(s)
背景 我在vscode里正常拉取代码,突然就报了如题所示的错误。 原因 因为vscode的拉取按钮执行的实际命令是:git pull --tags origin branch-name,该命令的实际含义是从远程仓库拉取指定的分支和该远程仓库上的所有标签。 在拉取标签时本地的…...
Python将字符串用特定字符分割并前面加序号
Python将字符串用特定字符分割并前面加序号 Python将字符串用特定字符分割并前面加序号,今天项目中就遇到,看着不难,得花点时间搞出来急用啊,在网上找了一圈,没发现有完整流程的文章。所以就搞出来并写了这个文章。仅…...
【第16章】Vue实战篇之跨域解决
文章目录 前言一、浏览器跨域二、配置代理1.公共请求2.代理配置 总结 前言 前后端项目分离衍生出浏览器跨域问题,开发之前我们通过配置代理解决这个问题。 一、浏览器跨域 浏览器的跨域问题主要是由于浏览器的同源策略导致的。同源策略是浏览器的一个安全功能&…...
【PB案例学习笔记】-22制作一个语音朗读金额小应用
写在前面 这是PB案例学习笔记系列文章的第22篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...
glmark2代码阅读总结
glmark2代码阅读总结 一、总体 用输入参数生成testbench项用scene和benchmark管理进行复用通过类的重载,创建出不同的分支和具体的实现点,如scene和mainloop类用例执行又规划,每个scene都统一有setup,等使用scene的继承关系&…...
第 6 章 监控系统 | 监控套路 - 总结
前面,我们使用 Prometheus + Grafana + Node Exporter 实现虚拟机监控及告警。 那么,😇 监控的套路究竟是什么呢? 第 1 步:暴露 metrics,通过某个 exporter 将 metrics 暴露出来第 2 步:配置 Prometheus 抓取上面暴露的 metrics 数据第 3 步:加速 metrics 显示,配置…...
VsCode中C文件调用其他C文件函数失败
之前一直使用CodeBlocks,最近使用vscode多,感觉它比较方便,但在调用其他C文件的时候发现报错以下内容基于单C文件运行成功,否则请移步 博文:VSCode上搭建C/C开发环境 报错信息 没有使用CodeRunner插件,弹…...
从Transformer到RAG:LLM实战开发全链路指南与工程实践
1. 项目概述:一本面向开发者的LLM实战开发指南最近几年,大语言模型(LLM)的发展速度让人目不暇接。从最初的GPT-3到如今遍地开花的开源模型,从只能处理文本到能“看懂”图像、生成代码,LLM正在重塑我们构建软…...
Windows Defender彻底移除工具:2025终极完整使用教程
Windows Defender彻底移除工具:2025终极完整使用教程 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_mirrors/wi/w…...
使用taotoken后c语言项目调用大模型的延迟与稳定性实际体验
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用taotoken后c语言项目调用大模型的延迟与稳定性实际体验 在开发一个需要集成大模型能力的C语言桌面应用时,我们面临…...
专利撰写难、公开不规范,patent-disclosure-skill:一站式专利公开技巧工具,搞定专利文书规范撰写难题
在知识产权越来越受重视的当下,不管是科研人员、技术开发者,还是企业知识产权相关从业者,在专利相关工作中,总会遇到各种各样的棘手问题。 很多人深耕技术研发,好不容易做出创新成果,可一到专利公开、文书梳…...
如何用开源视频字幕工具VideoSrt在3分钟内完成专业字幕制作
如何用开源视频字幕工具VideoSrt在3分钟内完成专业字幕制作 【免费下载链接】video-srt-windows 这是一个可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具。 项目地址: https://gitcode.com/gh_mirrors/vi/video-srt-windows 你是否还在为视频字幕制作…...
XYBotV2:开发者如何快速构建可扩展的智能对话机器人框架
1. 项目概述:一个面向开发者的智能对话机器人框架最近在GitHub上看到一个挺有意思的项目,叫XYBotV2。乍一看标题,可能很多人会以为这又是一个普通的聊天机器人,但如果你点进去仔细研究一下,就会发现它其实是一个为开发…...
从淘宝几块钱的2804云台电机开始,手把手教你DIY一个桌面机械臂关节(STM32/GD32 + SimpleFOC)
从零打造低成本机械臂关节:2804云台电机FOC控制实战指南 在创客圈里,机械臂项目总是让人既向往又却步——商用伺服电机动辄上千元的单价,让许多爱好者望而却步。但当我发现淘宝上仅售几元的2804云台电机时,一个大胆的想法诞生了&a…...
深入GD32F407时钟树:对比STM32F4,聊聊国产MCU时钟设计的异同与调试技巧
深入解析GD32F407时钟树:从STM32F4迁移的实战指南 当工程师第一次将STM32F4项目移植到GD32F407平台时,最常遇到的"幽灵问题"往往与时钟配置有关。我曾亲眼见证一个团队花费两周时间追踪CAN总线通信异常,最终发现仅仅是APB1时钟分频…...
保姆级教程:用Python复现红外小目标检测的LCM算法(附完整代码)
从零实现红外小目标检测:LCM算法Python实战指南 在计算机视觉领域,红外小目标检测一直是颇具挑战性的任务。不同于常规物体检测,红外图像中的目标往往只有几个像素大小,缺乏纹理和形状特征。传统基于深度学习的方法在这种场景下常…...
私域团队如何用企业微信 API 提升客户维护效率?
一、 场景描述:为什么你的团队每天都在“瞎忙”? 很多私域团队看似忙碌,实则效率低下。典型的现象包括: • 重复回答:每天 70% 的时间在复制粘贴相同的话术(如:发货时间、优惠券怎么领ÿ…...
