Java stream groupingBy sorted 实现多条件排序与分组的最佳实践
1. 数据初始化
这一部分代码用于创建 Product 对象并将它们添加到 result 列表中。
// 初始化数据
List<Product> result = new ArrayList<>();
List<Product> resp = new ArrayList<>();// 添加产品数据
result.add(new Product("手机A", 1500, "电子", 3, 5));
result.add(new Product("手机B", 1600, "电子", 3, 5));
result.add(new Product("手机C", 1800, "电子", 3, 5));
result.add(new Product("电脑A", 13000, "电子", 3, 6));
result.add(new Product("电脑B", 15000, "电子", 3, 6));
result.add(new Product("电脑C", 18000, "电子", 3, 6));result.add(new Product("床C", 7000, "家具", 1, 4));
result.add(new Product("椅子A", 500, "家具", 1, 3));
result.add(new Product("椅子B", 400, "家具", 1, 3));
result.add(new Product("椅子C", 300, "家具", 1, 3));result.add(new Product("牙膏A", 15, "洗护", 2, 1));
result.add(new Product("牙膏B", 25, "洗护", 2, 1));
result.add(new Product("牙膏C", 18, "洗护", 2, 1));
result.add(new Product("洗面奶A", 60, "洗护", 2, 2));
result.add(new Product("洗面奶B", 70, "洗护", 2, 2));
result.add(new Product("洗面奶C", 80, "洗护", 2, 2));
说明
Product类:表示一个产品对象,包含以下属性:name:产品名称。price:产品价格。type:产品类型(如电子、家具、洗护)。seq0和seq1:排序辅助字段。
result列表:存储所有产品对象。resp列表:用于存储最终输出的结果。
2. 按价格排序并分组
这一部分代码对 result 列表中的产品按价格排序后,按 type 字段分组。
// 按价格排序并分组
Map<String, List<Product>> collect = result.stream().sorted(Comparator.comparing(Product::getPrice)) // 按价格升序排序.collect(Collectors.groupingBy(Product::getType, // 按类型分组LinkedHashMap::new, // 保持分组顺序Collectors.toList() // 分组后每组存为 List));
说明
- 排序:使用
Comparator.comparing(Product::getPrice)对产品按价格升序排序。 - 分组:使用
Collectors.groupingBy按type字段分组。 - 结果:
collect是一个Map,键为产品类型(如 “电子”、“家具”),值为对应类型的产品列表。
3. 对分组后的数据排序
这一部分代码对每个分组内的产品列表进行排序,先按 seq1 正序,再按价格倒序。
// 对分组后的数据按 seq1 正序和价格倒序排序
Map<String, List<Product>> sortedCollect = result.stream().collect(Collectors.groupingBy(Product::getType, // 按类型分组LinkedHashMap::new, // 保持分组顺序Collectors.collectingAndThen(Collectors.toList(), // 先收集到 Listlist -> list.stream().sorted(Comparator.comparing(Product::getPrice).reversed()) // 价格倒序.sorted(Comparator.comparing(Product::getSeq1)) // seq1 正序.collect(Collectors.toList()) // 排序后收集为 List)));
说明
- 分组:与上一步类似,按
type字段分组。 - 排序逻辑:
- 价格倒序:
Comparator.comparing(Product::getPrice).reversed()。 seq1正序:Comparator.comparing(Product::getSeq1)。- 排序优先级:先按
seq1排序,再按价格排序。
- 价格倒序:
- 结果:
sortedCollect是一个Map,每个分组内的产品列表已按上述规则排序。
4. 对分组的键排序
这一部分代码对分组的键(即产品类型)按字典序排序。
// 对分组后的 key 进行排序
Map<String, List<Product>> sortedMap2 = sortedCollect.entrySet().stream().sorted(Map.Entry.comparingByKey()) // 按键(类型)排序.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(oldVal, newVal) -> oldVal,LinkedHashMap::new // 保持插入顺序));
说明
- 排序逻辑:
Map.Entry.comparingByKey()按键(类型)字典序排序。 - 结果:
sortedMap2是一个按类型排序的Map,每个分组内的产品列表已按规则排序。
5. 按顺序取出每组的第 i 个元素
这一部分代码从每个分组中依次取出第 i 个元素,直到所有元素都被取出。
// 遍历分组数据,按顺序取出每组的第 i 个元素
int index = 0;
boolean done = false;while (!done) {done = true;for (String key : sortedMap2.keySet()) {List<Product> group = sortedMap2.get(key);if (index < group.size()) {String name = sortedMap2.get(key).get(index).name;System.out.println("name: " + name);resp.add(group.get(index)); // 添加到结果列表done = false; // 如果还有未取出的元素,继续循环}}index++;
}
说明
- 逻辑:
- 遍历每个分组,取出第
index个元素。 - 如果某个分组的元素已取完,则跳过。
- 当所有分组的元素都取完时,退出循环。
- 遍历每个分组,取出第
- 结果:
resp列表按顺序存储所有产品。
6. 按每组的第 i 个元素重新排序
这一部分代码实现了另一种遍历方式,按每组的第 i 个元素重新排序。
// 计算每组的最大长度
int count = 0;
for (String key : sortedMap2.keySet()) {count = Math.max(count, sortedMap2.get(key).size());
}// 按每组的第 i 个元素重新排序
int j = 0;
for (int i = 0; i < count; i++) {for (String key : sortedMap2.keySet()) {if (i >= sortedMap2.get(key).size()) {continue; // 跳过超出范围的元素}String name = sortedMap2.get(key).get(i).name;System.out.println("name: " + name);resp.add(j, sortedMap2.get(key).get(i)); // 插入到结果列表j++;}
}
说明
- 逻辑:
- 计算每组的最大长度
count。 - 遍历每组的第
i个元素,按顺序插入到resp列表中。
- 计算每组的最大长度
- 结果:
resp列表存储按每组第i个元素排序的结果。
7. 产品类定义
Product 类是代码的核心数据结构,定义如下:
static class Product {String name;int price;String type;int seq0;int seq1;public Product(String name, int price, String type, int seq0, int seq1) {this.name = name;this.price = price;this.type = type;this.seq0 = seq0;this.seq1 = seq1;}public String getName() {return name;}public int getPrice() {return price;}public String getType() {return type;}public int getSeq0() {return seq0;}public int getSeq1() {return seq1;}
}
总结
通过拆分代码,我们可以清晰地看到每个部分的功能:
- 数据初始化。
- 按价格排序并分组。
- 对分组内的产品排序。
- 对分组的键排序。
- 按顺序取出每组的第
i个元素。 - 按每组的第
i个元素重新排序。
如果需要进一步优化或补充说明,请随时告知!
相关文章:
Java stream groupingBy sorted 实现多条件排序与分组的最佳实践
1. 数据初始化 这一部分代码用于创建 Product 对象并将它们添加到 result 列表中。 // 初始化数据 List<Product> result new ArrayList<>(); List<Product> resp new ArrayList<>();// 添加产品数据 result.add(new Product("手机A", 1…...
JAVA:代理模式(Proxy Pattern)的技术指南
1、简述 代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理,以控制对这个对象的访问。通过代理模式,我们可以在不修改目标对象代码的情况下扩展功能,满足特定的需求。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 2、什…...
爬取Q房二手房房源信息
文章目录 1. 实战概述2. 网站页面分析3. 编写代码爬取Q房二手房房源信息3.1 创建项目与程序3.2 运行程序,查看结果 4. 实战小结 1. 实战概述 本次实战项目旨在通过编写Python爬虫程序,抓取深圳Q房网上的二手房房源信息。我们将分析网页结构,…...
Ansible自动化运维(五) 运维实战
Ansible自动化运维这部分我将会分为五个部分来为大家讲解 (一)介绍、无密钥登录、安装部署、设置主机清单 (二)Ansible 中的 ad-hoc 模式 模块详解(15)个 (三)Playbook 模式详解 …...
K-means算法的python实现
K-means算法步骤 初始化质心:输入初始的质心位置。分配样本:将每个数据点分配到离它最近的质心对应的簇中。更新质心:对每个簇中的所有数据点,计算它们的均值,并将均值更新为新的质心。重复步骤2和3,直到质…...
客户端(浏览器)vue3本地预览txt,doc,docx,pptx,pdf,xlsx,csv,
预览文件 1、入口文件preview/index.vue2、预览txt3、预览doc4、预览pdf5、预览pptx6、预览xlsx7、预览csv 1、入口文件preview/index.vue 预览样式,如pdf 文件目录如图所示: 代码如下 <template><div class"preview-wrap" ref&…...
[SZ901]JTAG高速下载设置(53Mhz)
SZ901最高支持JTAG 53MHz的时钟频率,下载bit文件和固化程序的速度提升非常明显。 首先设置参数 1,将JTAG0 分频系数修改为3 2,设置参数,更新参数。(完成) 打开VIVADO VIVADO 正常识别FPGA,速…...
docker springboot 运维部署详细实例
环境安装 [rootiZbp1dcnzq7pzpg9607m6pZ ~]# docker -v Docker version 26.1.4, build 5650f9b镜像构建 Dockerfile 文件内容 FROM openjdk:8 # Author Info 创建人信息 MAINTAINER ratelcloudfoxmail.com ENV PORT20001 EXPOSE 20001 RUN mkdir /usr/local/ratel-boot-serv…...
Linux 查看目录命令 ls 详细介绍
Linux 和 Unix 系统中 ls 命令是用于列出目录内容。用户可以查看指定目录下的文件和子目录,还可以获取有关这些文件和子目录的详细信息。 基本语法: ls [选项] [目录]如果不指定目录,ls 将列出当前工作目录下的内容。 01、-a 或 --all ls…...
React Native状态管理器Redux、MobX、Context API、useState
Redux、MobX、Context API、useState都是React中用于状态管理的工具,但它们各自有不同的特点和使用场景。 Redux 介绍: Redux是一个JavaScript状态管理库,最初由Dan Abramov和Andrew Clark于2015年开发。它基于Flux架构,强调状态…...
Three.js资源-模型下载网站
在使用 Three.js 进行 3D 开发时,拥有丰富的模型资源库可以大大提升开发效率和作品质量。以下是一些推荐的 Three.js 模型下载网站,它们提供了各种类型的 3D 模型,适合不同项目需求。无论你是需要逼真的建筑模型,还是简单的几何体…...
linux 添加默认网关
在linux 可以使用 route 命令添加默认网关,假设添加的默认网关是192.168.159.2 添加方式如下: route add default gw 192.168.159.2 以上命令只需要把add 改成 del ,就能删除刚才添加的路由 route del default gw 192.168.159.2 #该命…...
【学习笔记】深入浅出详解Pytorch中的View, reshape, unfold,flatten等方法。
文章目录 一、写在前面二、Reshape(一)用法(二)代码展示 三、Unfold(一)torch.unfold 的基本概念(二)torch.unfold 的工作原理(三) 示例代码(四&a…...
CTFHUB-web(SSRF)
内网访问 点击进入环境,输入 http://127.0.0.1/flag.php 伪协议读取文件 /?urlfile:///var/www/html/flag.php 右击查看页面源代码 端口扫描 1.根据题目提示我们知道端口号在8000-9000之间,使用bp抓包并进行爆破 POST请求 点击环境,访问flag.php 查看页…...
分解质因数
给定 n个正整数 ,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。 输入格式 第一行包含整数 n 接下来 n行,每行包含一个正整数 。 输出格式 对于每个正整数 ,按照从小到大的顺序输出其分解质因数后&…...
前景物体提取
参考:精选课:C完整的实现双目摄像头图像采集、双目摄像头畸变矫正、前景物体提取、生成视差图、深度图、PCL点云图 前景物体提取是计算机视觉中的一个重要技术,可以用于视频监控、虚拟现实和计算机视觉等领域。 1.前景物体提取的原理 前景…...
Kotlin复习
一、Kotlin类型 1.整数 2.浮点 显示转换: 所有数字类型都支持转换为其他类型,但是转换前会检测长度。 toByte(): Byte toShort(): Short toInt(): Int toLong(): Long toFloat(): Float toDouble(): Double 不同进制的数字表示方法(为了提高…...
【AI日记】24.12.17 kaggle 比赛 2-6 | 把做饭看成一种游戏 | 咖喱牛肉
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 参加:kaggle 比赛 Regression with an Insurance Dataset时间:9 小时睡得好很重要 读书 书名:富兰克林自传时间:0.5 小时阅读原因:100 美元纸…...
操作系统(14)请求分页
前言 操作系统中的请求分页,也称为页式虚拟存储管理,是建立在基本分页基础上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能的一种内存管理技术。 一、基本概念 分页:将进程的逻辑地址空间分成若干个大小相等的页&am…...
uniapp navigateTo、redirectTo、reLaunch等页面路由跳转方法的区别
uni.switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 // app.json {"tabBar": {"list": [{"pagePath": "index","text": "首页"},{"pagePath": "other","text&…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
