Java-Collectors.groupingBy
Java中的Collectors类的groupingBy()方法用于按某些属性对对象进行分组并将结果存储在Map实例中。
当我我们想利用它的特性,我们需要指定一个属性来执行分组。此方法提供的函数类似于SQL的GROUP BY子句。
用法:
public static Collector<T, ?, Map<K, List>> groupingBy(Function classifier)
类型参数:此方法采用两个类型参数:
T-这是输入元素的类型。
K-这是要转换的输入元素的类型。
参数:此方法接受两个强制性参数:
Function-这是要应用于输入元素的属性。
Classifier-它用于将输入元素映射到目标映射中。
返回值:它返回一个Collector作为Map。
Collectors.groupingBy根据一个或多个属性对集合中的项目进行分组
1、测试数据准备
1.1、首先,创建一个实体生产实体类,用于模拟测试数据
@Data
public class Product {
private Long id;
private Integer num;
private BigDecimal price;
private String name;
private String category;
private Integer size;
public Product(Long id, Integer num, BigDecimal price, String name, String category, Integer size) {
this.id = id;
this.num = num;
this.price = price;
this.name = name;
this.category = category;
this.size = size;
}
}
1.2、创建测试类
代码结构如下:

构造测试数据:
Product prod1 = new Product(1L, 1, new BigDecimal("15.5"), "面包", "零食",1);
Product prod2 = new Product(2L, 2, new BigDecimal("20"), "饼干", "零食",1);
Product prod3 = new Product(3L, 3, new BigDecimal("30"), "月饼", "零食",2);
Product prod4 = new Product(4L, 3, new BigDecimal("10"), "青岛啤酒", "啤酒",1);
Product prod5 = new Product(5L, 10, new BigDecimal("15"), "百威啤酒", "啤酒",1);
Product prod6 = new Product(6L, 7, new BigDecimal("25"), "百威啤酒", "啤酒",1);
Product prod7 = new Product(7L, 1, new BigDecimal("15.4"), "面包", "零食",1);
Product prod8 = new Product(8L, 7, new BigDecimal("25.5"), "百威啤酒", "啤酒",2);
List<Product> prodList = List.of(prod1, prod2, prod3, prod4, prod5, prod6,prod7,prod8);
2、开始测试
2.1、按照类别分组
Map<String, List<Product>> map1 = prodList.stream().collect(Collectors.groupingBy(Product::getCategory));
Set<Map.Entry<String, List<Product>>> entries1 = map1.entrySet();
for (Map.Entry<String, List<Product>> entry : entries1) {
System.out.println(entry);
}
分组结果
==============================按照类别分组=============================================
啤酒=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒', size=1}, Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒', size=1}, Product{id=6, num=7, price=25, name='百威啤酒', category='啤酒', size=1}, Product{id=8, num=7, price=25.5, name='百威啤酒', category='啤酒', size=2}]
零食=[Product{id=1, num=1, price=15.5, name='面包', category='零食', size=1}, Product{id=2, num=2, price=20, name='饼干', category='零食', size=1}, Product{id=3, num=3, price=30, name='月饼', category='零食', size=2}, Product{id=7, num=1, price=15.4, name='面包', category='零食', size=1}]
2.2、按照多个属性拼接分组(类别+名称)
Map<String, List<Product>> map2 = prodList.stream()
.collect(Collectors.groupingBy(new Function<Product, String>() {
@Override
public String apply(Product product) {
return product.getCategory() + "_" + product.getName();
}
}
)
);
Set<Map.Entry<String, List<Product>>> entries2 = map2.entrySet();
for (Map.Entry<String, List<Product>> entry : entries2) {
System.out.println(entry);
}
分组结果
==============================按照多个属性拼接分组(类别——名称)=============================================
零食_月饼=[Product{id=3, num=3, price=30, name='月饼', category='零食', size=2}]
零食_面包=[Product{id=1, num=1, price=15.5, name='面包', category='零食', size=1}, Product{id=7, num=1, price=15.4, name='面包', category='零食', size=1}]
啤酒_百威啤酒=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒', size=1}, Product{id=6, num=7, price=25, name='百威啤酒', category='啤酒', size=1}, Product{id=8, num=7, price=25.5, name='百威啤酒', category='啤酒', size=2}]
啤酒_青岛啤酒=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒', size=1}]
零食_饼干=[Product{id=2, num=2, price=20, name='饼干', category='零食', size=1}]
2.3、按照num数值的大小来
Map<String, List<Product>> map3 = prodList.stream().collect(Collectors.groupingBy(item -> {
if (item.getNum() > 3) {
return "num大于3";
} else if (item.getNum() < 3) {
return "num小于3";
} else {
return "num等于3";
}
}));
Set<Map.Entry<String, List<Product>>> entries3 = map3.entrySet();
for (Map.Entry<String, List<Product>> entry : entries3) {
System.out.println(entry);
}
分组结果
===========================按照num数值的大小来================================================
num小于3=[Product{id=1, num=1, price=15.5, name='面包', category='零食', size=1}, Product{id=2, num=2, price=20, name='饼干', category='零食', size=1}, Product{id=7, num=1, price=15.4, name='面包', category='零食', size=1}]
num等于3=[Product{id=3, num=3, price=30, name='月饼', category='零食', size=2}, Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒', size=1}]
num大于3=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒', size=1}, Product{id=6, num=7, price=25, name='百威啤酒', category='啤酒', size=1}, Product{id=8, num=7, price=25.5, name='百威啤酒', category='啤酒', size=2}]
2.4、先按照类别分组,再按照num分组
Map<String, Map<String, List<Product>>> map4 = prodList.stream()
.collect(Collectors.groupingBy(Product::getCategory, Collectors.groupingBy(item -> {
if (item.getNum() >= 8) {
return "num大于等于8";
} else {
return "num小于8";
}
})));
Set<Map.Entry<String, Map<String, List<Product>>>> entries4 = map4.entrySet();
for (Map.Entry<String, Map<String, List<Product>>> entry : entries4) {
System.out.println(entry);
}
分组结果
===========================先按照类别分组,再按照num分组================================================
啤酒={num小于8=[Product{id=4, num=3, price=10, name='青岛啤酒', category='啤酒', size=1}, Product{id=6, num=7, price=25, name='百威啤酒', category='啤酒', size=1}, Product{id=8, num=7, price=25.5, name='百威啤酒', category='啤酒', size=2}], num大于等于8=[Product{id=5, num=10, price=15, name='百威啤酒', category='啤酒', size=1}]}
零食={num小于8=[Product{id=1, num=1, price=15.5, name='面包', category='零食', size=1}, Product{id=2, num=2, price=20, name='饼干', category='零食', size=1}, Product{id=3, num=3, price=30, name='月饼', category='零食', size=2}, Product{id=7, num=1, price=15.4, name='面包', category='零食', size=1}]}
2.5、先按照类别分组,再聚合求总数
Map<String, Long> map5 = prodList.stream()
.collect(Collectors.groupingBy(Product::getCategory, Collectors.counting()));
Set<String> strings5 = map5.keySet();
for (String s : strings5) {
System.out.println(s + "---" + "总数:" + map5.get(s));
}
分组结果
===========================先按照类别分组,再聚合求总数================================================
啤酒---总数:4
零食---总数:4
2.6、先按照类别分组,再聚合运算(把num相加)
Map<String, Integer> map6 = prodList.stream()
.collect(Collectors.groupingBy(Product::getCategory, Collectors.summingInt(Product::getNum)));
Set<String> strings6 = map6.keySet();
for (String s : strings6) {
System.out.println(s + "---" + "num相加后:" + map6.get(s));
}
分组结果
===========================先按照类别分组,再聚合运算(把num相加)================================================
啤酒---num相加后:27
零食---num相加后:7
Java-Collectors.groupingBy的更多相关文章
- Java 8 – Stream Collectors groupingBy count examples
Java 8 – Stream Collectors groupingBy count examples 1. Group By, Count and Sort1.1 Group by a List ...
- Collectors.groupingBy分组后的排序问题
默认groupingBy代码里会生成一个HashMap(hashMap是无序的,put的顺序与get的顺序不一致) HashMap是无序的,HashMap在put的时候是根据key的hashcode进 ...
- [转]深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)
以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...
- Java基础系列-Collector和Collectors
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...
- 深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)
转载:http://zh.lucida.me/blog/java-8-lambdas-inside-out-library-features/ 关于 深入理解 Java 8 Lambda(语言篇——l ...
- Java 8 - Stream Collectors分组的例子
1.分组依据,计数和排序 1.1按a分组List并显示它的总数. package com.mkyong.java8; import java.util.Arrays; import java.util ...
- Java 8 Stream 的终极技巧——Collectors 操作
1. 前言 昨天在 Collection移除元素操作 相关的文章中提到了 Collectors .相信很多同学对这个比较感兴趣,那我们今天就来研究一下 Collectors . 2. Collecto ...
- java stream中Collectors的用法
目录 简介 Collectors.toList() Collectors.toSet() Collectors.toCollection() Collectors.toMap() Collectors ...
- 【Java 基础】Collectors 使用小结
Collectors 与集合转换 Collectors toList streamArr.collect(Collectors.toList()); List<Integer> colle ...
- Java 8函数编程轻松入门(四)方法引用
C#中系统提供了许多IEnumerable的扩展方法.同样在Java 8中新引入了Collector类. 1.方法引用 定义: 简而言之:就是一个Lambda表达式.在Java 8中,我们我们会使用L ...
随机推荐
- ECharts 饼图指定颜色显示
一.通过setOption的color属性分配颜色范围 先介绍这里提到的color属性 color:调色盘颜色列表.如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色. 默认为: ['#5 ...
- 2 .NET Core笔试题
1.说说在Linux系统部署ASP.NET Core项目的步骤. 2.说说热重载是什么. 3.如何理解鉴权和授权两个词 4.说说.NET7包含了几大方向的开发? 5.如何理解云原生? 6.ASP.NE ...
- DESIR队列:早期axSpA的脊柱放射学进展
DESIR队列:早期axSpA的脊柱放射学进展 EULAR2015; PresentID: FRI0234 SPINAL RADIOGRAPHIC PROGRESSION IN EARLY AXIAL ...
- 代码随想录算法训练营day08 | leetcode 344.反转字符串/541. 反转字符串II / 剑指Offer05.替换空格/151.翻转字符串里的单词/剑指Offer58-II.左旋转字符串
基础知识 // String -> char[] char[] string=s.toCharArray(); // char[] -> String String.valueOf(str ...
- Android:LitePal 在第一次创建表之后第二次创建新的表不生效
因为业务需求的增长,后续需要继续创建新的表,有可能代码没有任何报错,同时数据库也没有任何新的表加入进来. 修改 litepal.xml 的 version,如果之前是 1,那么修改为 2,总之比之前 ...
- 封装avalonia指定组件允许拖动的工具类
封装avalonia指定组件允许拖动的工具类 创建Avalonia的MVVM项目,命名DragDemo ,然后将项目的Nuget包更新到预览版 <ItemGroup> <Packag ...
- nginx 安全漏洞(CVE-2021-23017) 版本升级
查看当前nginx版本信息 # ./sbin/nginx -V nginx version: nginx/1.20.1 built by gcc 4.8.5 20150623 (Red Hat 4.8 ...
- 关于hbulider开发工具微信小程序请求跨域
问题描述: 1.thinkphp设置了跨域请求设置 2.接口在浏览器模式正常请求 3.微信小程序请求显示跨域 解决方案:
- windows自带xbox game bar如何更改录制视频保存位置
若要更改保存游戏剪辑的位置,请使用文件资源管理器根据需要将"捕获"文件夹移动到电脑上的任意位置. Windows 会将游戏剪辑和屏幕截图保存在该文件夹中(无论移动到哪里). ...
- Java实现简单薪水计算器相关操作代码
/** * 薪水计算器 * 1.通过键盘输入用户的月薪,每年是几个薪水 * 2.输出用户年薪 * 3.输出一行字"如果年薪超过10万,恭喜你超越了90%的国人:如果年薪超过了20万,恭喜你超 ...