java8分组求和_Java8 stream 中利用 groupingBy 进行多字段分组求和案例
Java8的groupingBy实现集合的分组,类似Mysql的group by分组功能,注意得到的是一个map
对集合按照单个属性分组、分组计数、排序
List items =
Arrays.asList("apple", "apple", "banana",
"apple", "orange", "banana", "papaya");
// 分组
Map> result1 = items.stream().collect(
Collectors.groupingBy(
Function.identity()
)
);
//{papaya=[papaya], orange=[orange], banana=[banana, banana], apple=[apple, apple, apple]}
System.out.println(result1);
// 分组计数
Map result2 = items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
// {papaya=1, orange=1, banana=2, apple=3}
System.out.println(result2);
Map finalMap = new LinkedHashMap<>();
//分组, 计数和排序
result2.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));
// {apple=3, banana=2, papaya=1, orange=1}
System.out.println(finalMap);
集合按照多个属性分组
1.多个属性拼接出一个组合属性
public static void main(String[] args) {
User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List list = new ArrayList();
list.add(user1);
list.add(user2);
list.add(user3);
Map> collect = list.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
//{zhangsan#beijing=[User{age=10, name='zhangsan', address='beijing'}, User{age=20, name='zhangsan', address='beijing'}],
// lisi#shanghai=[User{age=30, name='lisi', address='shanghai'}]}
System.out.println(collect);
}
private static String fetchGroupKey(User user){
return user.getName() +"#"+ user.getAddress();
}
2.嵌套调用groupBy
User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List list = new ArrayList();
list.add(user1);
list.add(user2);
list.add(user3);
Map>> collect
= list.stream().collect(
Collectors.groupingBy(
User::getAddress, Collectors.groupingBy(User::getName)
)
);
System.out.println(collect);
3. 使用Arrays.asList
我有一个与Web访问记录相关的域对象列表。这些域对象可以扩展到数千个。
我没有资源或需求将它们以原始格式存储在数据库中,因此我希望预先计算聚合并将聚合的数据放在数据库中。
我需要聚合在5分钟窗口中传输的总字节数,如下面的sql查询
select
round(request_timestamp, '5') as window, --round timestamp to the nearest 5 minute
cdn,
isp,
http_result_code,
transaction_time,
sum(bytes_transferred)
from web_records
group by
round(request_timestamp, '5'),
cdn,
isp,
http_result_code,
transaction_time
Map>>>>>> aggregatedData =
webRecords
.stream()
.collect(Collectors.groupingBy(WebRecord::getFiveMinuteWindow,
Collectors.groupingBy(WebRecord::getCdn,
Collectors.groupingBy(WebRecord::getIsp,
Collectors.groupingBy(WebRecord::getResultCode,
Collectors.groupingBy(WebRecord::getTxnTime,
Collectors.reducing(0,
WebRecord::getReqBytes(),
Integer::sum)))))));
这是可行的,但它是丑陋的,所有这些嵌套的地图是一个噩梦!要将地图“展平”或“展开”成行,我必须这样做
for (Date window : aggregatedData.keySet()) {
for (String cdn : aggregatedData.get(window).keySet()) {
for (String isp : aggregatedData.get(window).get(cdn).keySet()) {
for (String resultCode : aggregatedData.get(window).get(cdn).get(isp).keySet()) {
for (String txnTime : aggregatedData.get(window).get(cdn).get(isp).get(resultCode).keySet()) {
Integer bytesTransferred = aggregatedData.get(window).get(cdn).get(distId).get(isp).get(resultCode).get(txnTime);
AggregatedRow row = new AggregatedRow(window, cdn, distId...
如你所见,这是相当混乱和难以维持。
有谁知道更好的方法吗?任何帮助都将不胜感激。
我想知道是否有更好的方法来展开嵌套的映射,或者是否有一个库允许您对集合进行分组。
最佳答案
您应该为地图创建自定义密钥。最简单的方法是使用Arrays.asList:
Function> keyExtractor = wr ->
Arrays.asList(wr.getFiveMinuteWindow(), wr.getCdn(), wr.getIsp(),
wr.getResultCode(), wr.getTxnTime());
Map, Integer> aggregatedData = webRecords.stream().collect(
Collectors.groupingBy(keyExtractor, Collectors.summingInt(WebRecord::getReqBytes)));
在这种情况下,键是按固定顺序列出的5个元素。不是很面向对象,但很简单。或者,您可以定义自己的表示自定义键的类型,并创建适当的hashCode/equals实现。
补充知识:java8 新特性 Stream流 分组 排序 过滤 多条件去重 (最小、最大、平均、求和)
什么是 Stream?
Stream 是用函数式编程方式在集合类上进行复杂操作的工具,其集成了Java 8中的众多新特性之一的聚合操作,开发者可以更容易地使用Lambda表达式,并且更方便地实现对集合的查找、遍历、过滤以及常见计算等。话不多说,直接上代码。
List list = new ArrayList();
list = Arrays.asList(
new User("小强", 11, "男"),
new User("小玲", 15, "女"),
new User("小虎", 23, "男"),
new User("小雨", 26, "女"),
new User("小飞", 19, "男"),
new User("小玲", 15, "女")
);
//分组
Map> listMap = list.stream().collect(Collectors.groupingBy(User::getSex));
for(String key:listMap.keySet()){
System.out.print(key+"组:");
listMap.get(key).forEach(user -> System.out.print(user.getName()));
System.out.println();
}
//排序
list.stream().sorted(Comparator.comparing(user-> user.getAge()))
.forEach(user -> System.out.println(user.getName()));
//过滤
list.stream().filter(user -> user.getSex().equals("男")).collect(Collectors.toList())
.forEach(user -> System.out.println(user.getName()));
//多条件去重
list.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(
Comparator.comparing(user -> user.getAge() + ";" + user.getName()))), ArrayList::new))
.forEach(user -> System.out.println(user.getName()));
//最小值
Integer min = list.stream().mapToInt(User::getAge).min().getAsInt();
//最大值
Integer max = list.stream().mapToInt(User::getAge).max().getAsInt();
//平均值
Double average = list.stream().mapToInt(User::getAge).average().getAsDouble();
//和
Integer sum = list.stream().mapToInt(User::getAge).sum();
System.out.println("最小值:"+min+", 最大值"+max+", 平均值:"+average+", 和:"+sum);
//分组求和
Map collect = list.stream().collect(Collectors.groupingBy(User::getSex, Collectors.summarizingInt(User::getAge)));
IntSummaryStatistics statistics1 = collect.get("男");
IntSummaryStatistics statistics2 = collect.get("女");
System.out.println(statistics1.getSum());
System.out.println(statistics1.getAverage());
System.out.println(statistics1.getMax());
System.out.println(statistics1.getMin());
System.out.println(statistics1.getCount());
System.out.println(statistics2.getSum());
System.out.println(statistics2.getAverage());
System.out.println(statistics2.getMax());
System.out.println(statistics2.getMin());
System.out.println(statistics2.getCount());
//提取list中两个属性值,转为map
Map userMap = list.stream().collect(Collectors.toMap(User::getName, User::getSex));
System.out.println(JsonUtil.toJson(userMap))
//取出所有名字
List names = list.stream().map(User::getName).collect(Collectors.toList());
System.out.println(JsonUtil.toJson(names))
以上这篇Java8 stream 中利用 groupingBy 进行多字段分组求和案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持龙方网络。
java8分组求和_Java8 stream 中利用 groupingBy 进行多字段分组求和案例相关推荐
- stream对多个字段分组_Java8 stream 中利用 groupingBy 进行多字段分组
1.利用stream对数据进行分组并求和 public static void main(String[] args) { List items = Arrays.asList("apple ...
- java 多字段分组_java8 stream统计、汇总、多字段分组、多个列汇总统计
前言 本文将展示groupingBy收集器的多个示例,阅读本文需要先准备Java Stream和Java收集器Collector的知识. 一.GroupingBy收集器 Java8的Stream AP ...
- mysql中利用sql语句修改字段名称,字段长度等操作(亲测)
在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改表或字段的注释,把同字段属性调整到一块儿.这些操作可以在phpmyadmin或者别的m ...
- java7java8 集合中对象的某一个字段分组
Java8根据单个字段分组 //假设传入一个非空订单集合 List<BaseOrder> orderList;//想要按照订单号分组 Map<String, List<Base ...
- Eclipse中,对工作空间中的项目进行分组(在查询中,也可也选择这个分组)。
有时,一个空间中有很多项目,但是这其中有的是我们不需要的,这时我们不想让工作空间显示很多项目. 于是,我们可以采用下面的办法,对工作空间中的项目进行分组. 对工作空间中的项目进行分组的方法: 1.打开 ...
- c++中利用STL实现公司员工分组问题
#include<iostream>using namespace std; #include<vector> #include<string> #include& ...
- Java8新特性-使用Stream流来实现递归遍历树形结构(案例)
Java8新特性-Stream流 可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中的Stream流一次性把数据查出来 ...
- Liquibase中利用changelog增加表字段
之前已经利用0000000000-initial-schema.yaml创建过数据库和表了,为了不对之前的库表造成影响决定采用增加changelog文件的方式添加表字段 首先新创建了一个add_tab ...
- mysql 指定日期条件求和_如何在mysql中按每个日期对字段进行求和-问答-阿里云开发者社区-阿里云...
我正在尝试根据案件的日期查询QUERY总计字段罚款,何时但不成功,有解决方案吗? 我的桌子 NIP NAMA TANGGAL JENIS_KEHADIRAN DENDA 10016 Novi Iraw ...
- mysql查询包含字符串的记录,MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法...
首先我们建立一张带有逗号分隔的字符串. CREATE TABLE test(id int(6) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id),pname VARCH ...
最新文章
- 啊,我南非时间上午10点看成了。。
- Leetcode No.146 ****
- 一个月读完6本书?这些烧脑神书,你能读完1本,就是学霸!
- 无需付费,教你IDEA社区版中使用Tomcat
- Java面试 - List和Set比较,各自的子类比较
- PCA与图像压缩与去噪
- ubuntu14.04 remmina远程连接rdp服务器失败解决办法
- Django基础学习笔记:初识MTV模式
- C++_类和对象_C++多态_虚析构和纯虚析构函数---C++语言工作笔记074
- Android各控件绚丽Dome下载
- JDBC Statements, PreparedStatement和CallableStatement语句
- python三维曲面合并_绘制多面体的三维曲面
- 几何语言点C是ab的中点,备战中考:初中数学作图基本步骤及作图语言
- Photoshop——多变量+文字数据组替换+批处理详细操作
- 算法动态规划之杂交水果取名问题
- idea 汉化版 自定义类注释与方法注释 解决自定义注解出现红线
- (二)CDA 数据分析师Level1考试新版大纲解析(自己整理)PART 2 数据结构
- 2021 icpc 沈阳 J-Luggage Lock
- java 源码 股票_Java读取东方财富网上的股票信息源码
- Tree树状图的动态增删查改(上)生成树状图