java8 GroupingBy 用法大全
java8中,Collectors.groupingBy 会用得比较多,对其常见用法做一个汇总
1,模拟数据
Item
import java.math.BigDecimal;public class Item {private String name;private Integer quantity;private BigDecimal price;public Item(String name, int quantity, BigDecimal price) {this.name = name;this.quantity = quantity;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getQuantity() {return quantity;}public void setQuantity(Integer quantity) {this.quantity = quantity;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}
}
数据
public static List<Item> initData(){List<Item> items = Arrays.asList(new Item("apple", 20, new BigDecimal("4.99")),new Item("apple", 30, new BigDecimal("7.99")),new Item("apple", 10, new BigDecimal("9.99")),new Item("banana", 30, new BigDecimal("2.99")),new Item("banana", 20, new BigDecimal("6.99")),new Item("orange", 50, new BigDecimal("3.99")),new Item("orange", 20, new BigDecimal("8.99")),new Item("watermelon", 200, new BigDecimal("2.99")),new Item("watermelon", 100, new BigDecimal("5.99")),new Item("kiwi fruit", 40, new BigDecimal("5.88")),new Item("kiwi fruit", 20, new BigDecimal("8.88")));return items;}
2,用法
1,groupingBy
// 根据水果名称分组private static void groupingBy(){List<Item> items = initData();Map<String, List<Item>> itemGroupBy = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName));System.out.println(JSON.toJSONString(itemGroupBy));}
结果:
{"orange": [{"name": "orange","price": 3.99,"quantity": 50}, {"name": "orange","price": 8.99,"quantity": 20}],"banana": [{"name": "banana","price": 2.99,"quantity": 30}, {"name": "banana","price": 6.99,"quantity": 20}],"apple": [{"name": "apple","price": 4.99,"quantity": 20}, {"name": "apple","price": 7.99,"quantity": 30}, {"name": "apple","price": 9.99,"quantity": 10}],"kiwi fruit": [{"name": "kiwi fruit","price": 5.88,"quantity": 40}, {"name": "kiwi fruit","price": 8.88,"quantity": 20}],"watermelon": [{"name": "watermelon","price": 2.99,"quantity": 200}, {"name": "watermelon","price": 5.99,"quantity": 100}]
}
2,groupingCounting
// 统计水果的种类private static void groupingCounting(){List<Item> items = initData();Map<String, Long> itemGroupCount = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName, Collectors.counting()));System.out.println(JSON.toJSONString(itemGroupCount));}
结果
{"orange": 2,"banana": 2,"apple": 3,"kiwi fruit": 2,"watermelon": 2
}
3,groupingSum
// 统计各水果的总数量private static void groupingSum(){List<Item> items = initData();Map<String, Integer> itemGroupSum = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,
Collectors.summingInt(Item::getQuantity)));System.out.println(JSON.toJSONString(itemGroupSum));}
结果
{"orange": 70,"banana": 50,"apple": 60,"kiwi fruit": 60,"watermelon": 300
}
4,groupingMax
// 统计各水果中数量最多的那个private static void groupingMax(){List<Item> items = initData();Map<String, Item> itemGroupMax = ListUtils.emptyIfNull(items).stream().collect(Collectors.groupingBy(Item::getName,Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Item::getQuantity)), Optional::get)));System.out.println(JSON.toJSONString(itemGroupMax));Map<String, Item> itemGroupMaxMap = ListUtils.emptyIfNull(items).stream().collect(Collectors.toMap(Item::getName, Function.identity(), BinaryOperator.maxBy(Comparator.comparingInt(Item::getQuantity))));System.out.println(JSON.toJSONString(itemGroupMaxMap));}
结果
{"orange": {"name": "orange","price": 3.99,"quantity": 50},"banana": {"name": "banana","price": 2.99,"quantity": 30},"apple": {"name": "apple","price": 7.99,"quantity": 30},"kiwi fruit": {"name": "kiwi fruit","price": 5.88,"quantity": 40},"watermelon": {"name": "watermelon","price": 2.99,"quantity": 200}
}
Collectors.collectingAndThen 聚合后再操作
其参数:
collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)
5,grouping mapping
// 统计各水果的价格private static void groupingSet(){List<Item> items = initData();Map<String, Set<BigDecimal>> itemGroupSet = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,Collectors.mapping(Item::getPrice, Collectors.toSet())));System.out.println(JSON.toJSONString(itemGroupSet));Map<String, List<BigDecimal>> itemGroupList = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,Collectors.mapping(Item::getPrice, Collectors.toList())));System.out.println(JSON.toJSONString(itemGroupList));}
结果
{"orange": [3.99, 8.99],"banana": [2.99, 6.99],"apple": [7.99, 9.99, 4.99],"kiwi fruit": [5.88, 8.88],"watermelon": [2.99, 5.99]
}
6,groupingMap
// 统计各水果的数量对应价格private static void groupingMap(){List<Item> items = initData();Map<String, Map<Integer, BigDecimal>> itemGroupMap = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName,Collectors.toMap(Item::getQuantity, Item::getPrice, (x, y) -> x)));System.out.println(JSON.toJSONString(itemGroupMap));Map<String, Map<Integer, BigDecimal>> itemGroupMap2 = ListUtils.emptyIfNull(items).stream()
.collect(Collectors.groupingBy(Item::getName, Collectors.collectingAndThen(Collectors.toMap(Item::getQuantity, Item::getPrice), v -> v)));System.out.println(JSON.toJSONString(itemGroupMap2));}
结果
{"orange": {50: 3.99,20: 8.99},"banana": {20: 6.99,30: 2.99},"apple": {20: 4.99,10: 9.99,30: 7.99},"kiwi fruit": {20: 8.88,40: 5.88},"watermelon": {100: 5.99,200: 2.99}
}
第一种更为简便
7,groupingAvg
// 统计各水果的平均数量 int double long 三种类型private static void groupingAvg(){List<Item> items = initData();Map<String, Double> itemGroupAvg = ListUtils.emptyIfNull(items).stream().collect(Collectors.groupingBy(Item::getName,Collectors.averagingInt(Item::getQuantity)));System.out.println(JSON.toJSONString(itemGroupAvg));}
结果
{"orange": 35.0,"banana": 25.0,"apple": 20.0,"kiwi fruit": 30.0,"watermelon": 150.0
}
总结:
常见使用聚合再进行map处理,用于匹配数据。了解Collectors.collectingAndThen的用法,聚合后再进行操作。写不来,就分两步写,先完成,再优化。
相关文章:
java8 GroupingBy 用法大全
java8中,Collectors.groupingBy 会用得比较多,对其常见用法做一个汇总 1,模拟数据 Item import java.math.BigDecimal;public class Item {private String name;private Integer quantity;private BigDecimal price;public Item(String nam…...
vue_router__WEBPACK_IMPORTED_MODULE_1__.default is not a constructor
你所建立的项目 是 vue2x ,但是却下载了 vue-router4x 而 vue-router4x 适用于 vue3x 所以你需要卸载 vue-router4x,重新下载 vue-router3x 卸载: npm uninstall vue-router 安装:(3版本) npm i vue-router3...
前端html2canvas和dom-to-image实现截图功能
目录 需求 历劫过程 截图知识点 html2canvas 文档地址 封装 使用教程 dom-to-image-more 文档地址 封装 使用教程 解决跨域问题 以下是我花了大把时间,薅秃头得出来的最终结果, dom-to-image-more截图时间快到可以让复杂的页面仅需2-3S就能完成截图,内容有点多…...
Hadoop平台集群之间Hive表和分区的导出和导入迁移(脚本)
要编写Shell脚本实现两个Hadoop平台集群之间Hive表和分区的导出和导入迁移 你可以使用Hive的EXPORT和IMPORT命令结合Hadoop的DistCp命令。下面是一个示例脚本: #!/bin/bash# 导出源Hive表的数据到HDFS source_hive_table"source_db.source_table" targe…...
Linux C语言实践eBPF
手动编译了解过程 通过对关键步骤make Msamples/bpf的实践,我们已经可以编译出内核源码中提供的ebpf样例。但这还不够我们充分地理解这个编译过程,我们将这编译过程拆解一下,拆解成可以一步步执行的那种,首先是环境准备ÿ…...
垃圾回收标记阶段算法
1.标记阶段的目的 主要是在GC在前,判断出哪些是有用的对象,哪些是需要回收的对象,只有被标记为垃圾对象,GC才会对其进行垃圾回收。判断对象是否为垃圾对象的两种方式:引用计数算法和可达性分析算法。 2.引用计数算法…...
泰晓科技发布 Linux Lab v1.2 正式版
导读近日消息,Linux Lab 是一套用于 Linux 内核学习、开发和测试的即时实验室,官方称其“可以极速搭建和使用,功能强大,用法简单”。 自去年 12 月份发布 Linux Lab v1.1 后,v1.2 正式版目前已经发布于 GitHub 及 Gite…...
王道数据结构-代码实操1(全注解版)
#include<stdio.h>void loveyou(int n){ // 传入参数类型为int型,在此函数中表示为n;返回值类型为void,即没有返回值; int i1; //定义了一个整数型变量i,且只在loveyou函数中有用;while(i…...
flink写入到kafka 大坑解析。
1.kafka能不能发送null消息? 能! 2 flink能不能发送null消息到kafka? 不能! public static void main(String[] args) throws Exception {StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(…...
MATLAB算法实战应用案例精讲-【深度学习】预训练模型-Subword
目录 前言 Subword 1. Subword介绍 分词器是做什么的? 为什么需要分词? 分词方法...
【HarmonyOS】实现从视频提取音频并保存到pcm文件功能(API6 Java)
【关键字】 视频提取类Extractor、视频编解码、保存pcm文件 【写在前面】 在使用API6开发HarmonyOS应用时,通常会开发一些音视频媒体功能,这里介绍如何从视频中提取音频保存到pcm文件功能,生成pcm音频文件后,就可使用音频播放类…...
Linux:shell命令运行原理和权限的概念
文章目录 shell和kernelshell的概念和原理Linux的权限文件的权限文件的类型文件的权限管理权限的实战应用 shell和kernel 从狭义上来讲,Linux是一个操作系统,我们叫它叫kernel,意思是核心,核心的意思顾名思义,就是最关…...
Javascript -- 数组prototype方法探究
一、数组prototype方法探究 1、不改变原数组 1. concat() 这个是数组拼接方法,可以将两个数组或多个数组拼接并返回一个包含两个数组或多个数组内容的新数组,不会改变原数组 方法里面理论上可以写入n个参数, const arr [1,2]; var str …...
android stduio 打开工程后直接报Connection refused解决
报错如下:Connection refused 解决方案: 打开gradle-wrapper.properties修改distributionUrl 将: distributionUrlhttp\://localhost/gradle/distributions/gradle-6.5-bin.zip 替换为: distributionUrlhttps\://services.gradle.org/distributions/gradle-6.5-bin.zip 错…...
搜索与图论(一)
一、DFS与BFS 1.1深度优先搜索(DFS) DFS不具有最短性 //排列数字问题 #include<iostream> using namespace std;const int N 10; int n; int path[N]; bool st[N];void dfs(int u) {if(u n){for(int i 0;i < n;i) printf("%d",path[i]);puts("&qu…...
百题千解计划【CSDN每日一练】“小明投篮,罚球线投球可得一分”(附解析+多种实现方法:Python、Java、C、C++、C#、Go、JavaScript)
这个心上人,还不知道在哪里,感觉明天就会出现。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌟[2] 2022年度博客之星人工智能领域TOP4🌟 🏅[3] 阿里云社区特邀专家博主🏅 🏆[4] CSDN-人工智能领域优质创作者�…...
lemon框架开发笔记
lemon框架开发笔记 JudgeUtils.isBlank() 字符串为 null 或者 "" ----返回true JudgeUtils.isNotBlankAll() 字符串全部不为 null 或者 "" ----返回true JudgeUtils.isBlankAll() 字符串全部为 null 或者 "" ----返回true// isBlank 是在isEmpt…...
Spark SQL快速入门
1. 了解Spark SQL 1.1 什么是Spark SQL Spark SQL是spark的一个模块,用于处理海量的结构化数据。 1.2 Spark SQL有什么特点?优点是什么? 特点: Spark SQL支持读取和写入多种格式的数据源,包括Parquet、JSON、CSV、…...
linux+Jenkins+飞书机器人发送通知(带签名)
文章目录 如何使用在linux 上安装python 环境发送消息python脚本把脚本上传倒linux上 jenkins 上执行脚本 如何使用 自定义机器人使用指南飞书官网https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot 在linux 上安装python 环境 yum install python3 python…...
react hooks
1 useEffect(setup,dependencies) 使用object.is来比较每个依赖项和它先前的值 依赖项为空数组的effect不会在组件任何props和state发生改变时重新运行 当useEffect依赖于外部传入props对象时,容易造成死循环 需要对依赖对象进行深比较 import { isEqual } from…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
