当前位置: 首页 > news >正文

Stream流的groupingBy

Stream流的groupingBy

简单使用

业务场景:现在有100个人,这些人都年龄分部在18-30岁之间。现要求把他们按照年龄进行分组
key:年龄
value:数据列表

public void listToMapGroup() {//这里假设通过listStreamService.list();方法查询了这100人List<Perple> list = perpleService.list();//按照age进行分组Map<Integer, List<Perple>> result = list.stream().collect(Collectors.groupingBy(Perple::getAge));//打印结果result.forEach((k, v) -> {System.out.println(k);System.out.println(v);System.out.println("--------------------");});
}

效果相当于是,把list这个集合里面存放的100个人每个人都调用Perple的getAge方法,按照getAge方法的返回值进行分组。每个组是一个Map<Integer, List>类型的对象。Map<Integer, List>的键是getAge的返回值,即,分组的依据。Map<Integer, List>的值是这个年龄对应组中的成员。

如果要进行排序

分组之后,是不能对每个分组进行比较的(也就无法排序),因为groupingBy是一个终结流。
Collectors.groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, A, D> downstream)
这里有两个思路:
1:提前排序,再进行分组
2:分组后,对Map进行处理,对其每个value排序

做法一:

提前排序,再进行分组.
这里还展示了一些groupingBy方法的扩展用法。

import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;public class Test {public static void main(String[] args) {Student student1 = new Student(1, 1);Student student2 = new Student(1, 1);Student student3 = new Student(2, 2);Student student4 = new Student(2, 3);Student student5 = new Student(3, 3);Student student6 = new Student(3, 4);Student student7 = new Student(4, 1);Student student8 = new Student(4, 1);Student student9 = new Student(4, 2);Student student10 = new Student(4, 1);List<Student> list = Arrays.asList(student1, student2, student3, student4, student5, student6, student7, student8, student9, student10);System.out.println("--------- 根据字段分组,求每个分组的sum ----------");Map<Integer, Integer> collect = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.summingInt(Student::getScore)));System.out.println(collect.toString());System.out.println("--------- 根据字段分组,求每个分组的count ----------");Map<Integer, Long> countMap = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.counting()));System.out.println(countMap.toString());System.out.println("--------- 根据字段分组,每个分组为:对象的指定字段 ----------");Map<Integer, List<Integer>> groupMap = list.stream().collect(Collectors.groupingBy(Student::getId, Collectors.mapping(Student::getScore, Collectors.toCollection(ArrayList::new))));System.out.println(groupMap.toString());System.out.println("--------- 根据字段分组,默认分组 ----------");Map<Integer, List<Student>> defaultGroupMap = list.stream().collect(Collectors.groupingBy(Student::getId));System.out.println(JSONObject.toJSONString(defaultGroupMap));System.out.println("--------- 根据字段分组,每个分组按照指定字段进行生序排序 ----------");Map<Integer, List<Student>> sortGroupMap = list.stream().sorted(Comparator.comparing(Student::getScore)).collect(Collectors.groupingBy(Student::getId));System.out.println(JSONObject.toJSONString(sortGroupMap));System.out.println("--------- 先排序,再分组 ----------");Map<Integer, List<Student>> reversedSortGroupMap = list.stream().sorted(Comparator.comparing(Student::getScore).reversed()).collect(Collectors.groupingBy(Student::getId));System.out.println(JSONObject.toJSONString(reversedSortGroupMap));}
}class Student {private Integer id;private Integer score;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getScore() {return score;}public void setScore(Integer score) {this.score = score;}public Student(Integer id, Integer score) {this.id = id;this.score = score;}
}

执行结果:

--------- 根据字段分组,求每个分组的sum ----------
{1=2, 2=5, 3=7, 4=5}
--------- 根据字段分组,求每个分组的count ----------
{1=2, 2=2, 3=2, 4=4}
--------- 根据字段分组,每个分组为:对象的指定字段 ----------
{1=[1, 1], 2=[2, 3], 3=[3, 4], 4=[1, 1, 2, 1]}
--------- 根据字段分组,默认分组 ----------
{1:[{"id":1,"score":1},{"id":1,"score":1}],2:[{"id":2,"score":2},{"id":2,"score":3}],3:[{"id":3,"score":3},{"id":3,"score":4}],4:[{"id":4,"score":1},{"id":4,"score":1},{"id":4,"score":2},{"id":4,"score":1}]}
--------- 根据字段分组,每个分组按照指定字段进行生序排序 ----------
{1:[{"id":1,"score":1},{"id":1,"score":1}],2:[{"id":2,"score":2},{"id":2,"score":3}],3:[{"id":3,"score":3},{"id":3,"score":4}],4:[{"id":4,"score":1},{"id":4,"score":1},{"id":4,"score":1},{"id":4,"score":2}]}
---------  先排序,再分组  ----------
{1:[{"id":1,"score":1},{"id":1,"score":1}],2:[{"id":2,"score":3},{"id":2,"score":2}],3:[{"id":3,"score":4},{"id":3,"score":3}],4:[{"id":4,"score":2},{"id":4,"score":1},{"id":4,"score":1},{"id":4,"score":1}]}

做法二:

先分组,再排序。
先将数据进行groupingBy,得到Map<Long, List>
在通过forEach对每个List进行排序

        Map<Long, List<StreamMapEntity>> map = getMap();System.out.println("------ flatMap 处理Map<Long,List<StreamMapEntity>> ------");System.out.println();System.out.println("初始数据:" + JSONObject.toJSONString(map));System.out.println();map.keySet().forEach(key -> map.computeIfPresent(key, (k, v) -> v.stream().sorted(Comparator.comparing(StreamMapEntity::getId).reversed()).collect(Collectors.toList())));System.out.println("处理map:对map内的每个list进行排序:");System.out.println(JSONObject.toJSONString(map));

执行结果:

------ flatMap 处理Map<Long,List<StreamMapEntity>> ------初始数据:{1111:[{"id":1,"name":"aa"},{"id":2,"name":"bb"},{"id":3,"name":"cc"},{"id":4,"name":"dd"}],2222:[{"id":5,"name":"ee"},{"id":6,"name":"ff"},{"id":7,"name":"gg"},{"id":8,"name":"hh"}]}处理map:对map内的每个list进行排序:
{1111:[{"id":4,"name":"dd"},{"id":3,"name":"cc"},{"id":2,"name":"bb"},{"id":1,"name":"aa"}],2222:[{"id":8,"name":"hh"},{"id":7,"name":"gg"},{"id":6,"name":"ff"},{"id":5,"name":"ee"}]}

相关文章:

Stream流的groupingBy

Stream流的groupingBy 简单使用 业务场景&#xff1a;现在有100个人&#xff0c;这些人都年龄分部在18-30岁之间。现要求把他们按照年龄进行分组 key&#xff1a;年龄 value&#xff1a;数据列表 public void listToMapGroup() {//这里假设通过listStreamService.list();方法…...

如何在不结束tcpdump的情况下复制完整的pcap

tcpdump正在运行的时候&#xff0c;他写入的pcap可能是不完整的&#xff0c;通常我们要结束掉tcpdump才能拿到完整的pcap&#xff0c;否则wireshark打开的时候会提示&#xff1a;The capture file appears to have been cut short in the middle of a packet。这可能是因为tcpd…...

maven POM文件总体配置说明

<project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd "> <!-- 父项目的坐…...

49.批处理命令(1/2)

目录 一批处理。 &#xff08;1&#xff09;批处理定义。 &#xff08;2&#xff09;常见命令。 &#xff08;2.1&#xff09;rem和:: &#xff08;2.2&#xff09;echo和。 &#xff08;2.3&#xff09;pause。 &#xff08;2.4&#xff09;errorlevel。 &#xff08;…...

react类式组件的生命周期和useEffect实现函数组件生命周期

概念 生命周期是一个组件丛创建,渲染,更新,卸载的过程,无论是vue还是react都具有这个设计概念,也是开发者必须熟练运用的,特别是业务开发,不同的生命周期做不同的事是很重要的. ....多说两句心得,本人是先接触vue的,无论是vue2还是vue3的生命周期,在理解和学习上都会比react更…...

ARM 基础学习记录 / 异常与GIC介绍

GIC概念 念课本&#xff08;以下内容都是针对"通用中断控制器&#xff08;GIC&#xff09;"而言&#xff0c;直接摘录的&#xff0c;有的地方可能不符人类的理解方式&#xff09;&#xff1a; 通用中断控制器&#xff08;GIC&#xff09;架构提供了严格的规范&…...

java压缩pdf体积,图片体积

pdf整体进行压缩,图片进行压缩 // 生成主证书的PDF路径 创建一个文件String pdfPath UploadDown.createFile(".pdf");outputStream new FileOutputStream(pdfPath);bufferedOutputStream new BufferedOutputStream(outputStream);writer PdfWriter.getInstance(…...

Ubuntu(WSL2) 安装最新版本的 GCC

要在 Ubuntu 上安装最新版本的 GCC&#xff0c;可以通过以下步骤进行操作&#xff1a; 1. 打开终端&#xff08;Terminal&#xff09; 2. 更新软件包列表&#xff0c;确保系统使用最新的软件包信息&#xff0c;运行以下命令&#xff1a; sudo apt update 3. 安装 GCC 软件包…...

lua 时间差功能概略

简介 在进行程序设计过程中&#xff0c;经常需要对某些函数、某些程序片断从开始运行到运行结束所耗费的时间进行一些量化。这种量化实际上就是计算时间差。 获取函数耗时情景如下&#xff1a; function time_used() --开始计时-- do something at here. --结束计时--时间差&…...

【C++11】左值引用,右值引用,移动/复制构造,完美转发

左值与右值 字面意思是可以放在等号左边的就是左值&#xff0c;只能放在等号右边的就是右值&#xff08;为何是“可以”“只能”&#xff1f;例如i是左值&#xff0c;但他依然可以放在等号右边&#xff09;。 严格上的定义&#xff1a;可以取地址的就是左值&#xff0c;反之为…...

解决找不到x3daudio1_7.dll的方法,快速解决x3daudio1_7.dll丢失问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到x3daudio1_7.dll”。这个问题可能是由于多种原因引起的&#xff0c;例如文件丢失、损坏或被病毒感染等。下面将详细介绍如何解决这个问题。 首先&#xff0c;我们需要了解x3daudio1_…...

LeetCode:2300. 咒语和药水的成功对数(C++)

目录 2300. 咒语和药水的成功对数 题目描述&#xff1a; 实现代码与解析&#xff1a; 二分 原理思路&#xff1a; 2300. 咒语和药水的成功对数 题目描述&#xff1a; 给你两个正整数数组 spells 和 potions &#xff0c;长度分别为 n 和 m &#xff0c;其中 spells[i] 表…...

【Spring生命周期核心底层源码之剖析】

文章目录 一、Spring生命周期核心底层源码剖析—扫描1.1、Spring底层扫描机制doScan方法源码剖析 一、Spring生命周期核心底层源码剖析—扫描 1.1、Spring底层扫描机制doScan方法源码剖析 其源代码如下&#xff1a; protected Set<BeanDefinitionHolder> doScan(Strin…...

关于Thread.sleep方法的一些使用

Thread.sleep方法的作用就是使当前线程暂停执行一段指定的时间。 它的参数是以ms为单位的时间参数&#xff0c;表示暂停时间长度。如Thread.sleep(1000);表示暂停1s。 这个方法通常用在以下一些情况&#xff1a; 1、模拟延迟&#xff1a;在某些情况下&#xff0c;我们希望在…...

MeterSphere | 前端入参加密

项目场景&#xff1a; 在 MeterSphere 开源框架中&#xff0c;解决前端手机号入参加密 解决方案&#xff1a; 导入 JavaScript 包采用加密算法 导入网上 JavaScript 包 // 1. 通过cdn加载网上的js文件 g new Packages.org.mozilla.javascript.tools.shell.Global(Packages.o…...

微服务如何做负载均衡?

笔者在参与联通某子公司时&#xff0c;遇到了这样一个问题。感觉比较实际&#xff0c;特来记录一波。 先看腾讯混元的解答&#xff1a; 微服务架构中&#xff0c;负载均衡是必不可少的。在微服务中&#xff0c;负载均衡可以通过以下几种方式来实现&#xff1a; 1. DNS轮询&am…...

C++高级编程:构建高效稳定接口与深入对象设计技巧

C高级编程&#xff1a;构建高效稳定接口与深入对象设计技巧 建立稳定接口 类是C中的主要抽象单位。你应该将抽象原则应用于你的类&#xff0c;尽可能将接口与实现分离。具体来说&#xff0c;你应该使所有数据成员私有&#xff0c;并可选择性地提供getter和setter方法。这就是…...

Qt——连接mysql增删查改(仓库管理极简版)

目录 UI布局设计 .pro文件 mainwindow.h main.cpp UI布局设计 .pro文件 QT core gui QT core gui sql QT sqlgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any …...

Panda3d 场景管理

Panda3d 场景管理 文章目录 Panda3d 场景管理有关分层场景图的重要信息NodePathNodePath 以及 Node 的函数调用模型文件文件格式加载模型文件将模型放置在场景图中模型缓存压缩模型异步加载模型通过回调函数进行 常见的状态变化修改节点的位置和姿态改变父级节点改变颜色隐藏和…...

京东数据分析(京东销量):2023年9月京东投影机行业品牌销售排行榜

鲸参谋监测的京东平台9月份投影机市场销售数据已出炉&#xff01; 根据鲸参谋电商数据分析平台的相关数据数据显示&#xff0c;9月份&#xff0c;京东平台投影机的销量为13万&#xff0c;环比下滑约17%&#xff0c;同比下滑约25%&#xff1b;销售额将近2.6亿&#xff0c;环比下…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...