java8 groupingby_Java8stream中利用groupingBy进行多字段分组求和

java8 groupingby_Java8stream中利用groupingBy进行多字段分组求和对集合按照单个属性分组、分组计数、排序Listitems=Arrays.asList(“apple”,”apple”,”banana”,”apple”,”orange”,”banana”,”papaya”);//分组Map>result1=items.stream().collect(Collectors.groupingBy(Function.identity()));…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

对集合按照单个属性分组、分组计数、排序

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

在java 8中,我当前的第一次尝试是这样的,我知道这个解决方案类似于Group by multiple field

names in java 8

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实现。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171385.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c语言延时函数nop,延时函数怎么写delay

    c语言延时函数nop,延时函数怎么写delay1.c语言延时函数delay,怎么算延时下面是delay函延迟函数里执行的都是空语句,也就是说通过循环执行空语句来达到延迟的目的.每执行一条语句,即使是空语句都要耗费电脑一些处理时间的,就是因为这个,在延迟函数里写一些无关紧要的东西,用来浪费电脑处理时间,从而达到延迟目的。数原型:原型:voidDelay(unsignedintnDelay){unsignedinti,j,k;…

    2022年6月18日
    32
  • altium 原理图reset unique id

    altium 原理图reset unique id当画模块原理图时 电路相同的模块可以单独建一个文件 然后复制粘贴 得到多个相同的原理图图纸然而 sheet 文件复制粘贴会出现 ID 相同的情况 UNIQUEID 在原理图和 pcb 里面相当于元器件的唯一身份许可 不可相同 有的时候我们操作不当造成 ID 相同怎么办呢 nbsp 在原理图界面 TOOL Convert Reset nbsp Componentuni AD17 即可选择对应的图纸或工程或打开的文

    2025年10月11日
    6
  • Mac 读写NTFS硬盘

    Mac 读写NTFS硬盘查看磁盘DeviceNode:【diskutilinfo磁盘路径】diskutilinfo/Volumes/CPBA_X64FRE_ZH-CN_DV5通过DeviceNode卸载磁盘:【sudoumount/dev/disk2s1】…

    2022年6月18日
    25
  • 【Java面试系列】SpringBoot面试题

    【Java面试系列】SpringBoot面试题目录1.SpringBoot面试题2.题目解析1、什么是SpringBoot?2、SpringBoot有哪些优点?3、什么是JavaConfig?4、如何重新加载SpringBoot上的更改,而无需重新启动服务器?5、SpringBoot中的监视器是什么?6、如何在SpringBoot中禁用Actuator端点安全性?7、如何在…

    2022年5月21日
    47
  • 多进程与多线程区别

    多进程与多线程区别在 Unix 上编程采用多线程还是多进程的争执由来已久 这种争执最常见到在 C S 通讯中服务端并发技术的选型上 比如 WEB 服务器技术中 Apache 是采用多进程的 perfork 模式 每客户连接对应一个进程 每进程中只存在唯一一个执行线程 nbsp Java 的 Web 容器 Tomcat Websphere 等都是多线程的 每客户连接对应一个线程 所有线程都在一个进程中 从 Unix 发展历史看 伴随着 Uni

    2025年8月3日
    4
  • iOS多用连接、反向协议、安全

    iOS多用连接、反向协议、安全

    2022年1月11日
    57

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号