处理对象集合,输出Map<String, Map<String, List<MyObject>>>格式数据,无序组合键处理方法

需求:对象有字段A,B,C,需要判断对象之间AB两个字段相同的对象

如:

对象1,A=aaa,B=bbb

对象2,A=aaa,B=bbb

对象3,A=bbb,B=aaa

对象4,A=bbb,B=aaa

那这四个对象都是属于相同对象,先根据C字段分组,再去判断组内数据AB字段,输出以C为分组的map,key为c的内容,value是一个map的list集合,里面的map的key是AB字段组合的无序组合键,value是相同无序组合键的对象集合

java 复制代码
package com.b2bwings.cc.core;

import lombok.Getter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;

public class TestClass {
    class MyObject {
        @Getter
        private String a;
        @Getter
        private String b;
        @Getter
        private String c;

        public MyObject(String a, String b, String c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }

    // 生成AB字段的无序组合键(如A=aaa,B=bbb和A=bbb,B=aaa生成相同键)
    private  String createCompositeKey(String a, String b) {
        String[] arr = {a, b};
        Arrays.sort(arr);
        return arr[0] + "|" + arr[1];
    }


    @Test
    void test() {
        // 实际数据源)
        List<MyObject> dataList = new ArrayList<>();
        dataList.add(new MyObject("aaa", "bbb","1"));
        dataList.add(new MyObject("bbb", "aaa","1"));
        dataList.add(new MyObject("bbb", "aaa","1"));
        dataList.add(new MyObject("ccc", "bbb","1"));
        dataList.add(new MyObject("bbb", "ccc","1"));
        dataList.add(new MyObject("bbb", "ccc","1"));
        dataList.add(new MyObject("aaa", "bbb","2"));
        dataList.add(new MyObject("aaa", "bbb","2"));
        dataList.add(new MyObject("bbb", "aaa","2"));
        dataList.add(new MyObject("bbb", "aaa","2"));
        dataList.add(new MyObject("aaa", "bbb","3"));
        dataList.add(new MyObject("aaa", "bbb","3"));
        dataList.add(new MyObject("bbb", "aaa","3"));
        dataList.add(new MyObject("bbb", "aaa","3"));
        dataList.add(new MyObject("aaa", "bbb","3"));
        dataList.add(new MyObject("aaa", "bbb","3"));
        dataList.add(new MyObject("bbb", "aaa","3"));
        dataList.add(new MyObject("bbb", "aaa","3"));

        Map<String, Map<String, List<MyObject>>> result = dataList.stream()
                .collect(Collectors.groupingBy(MyObject::getC))
                .entrySet().parallelStream()
                .collect(Collectors.toMap(
                        entry -> entry.getKey().toString(), // 关键修改点:Lambda替代方法引用
                        cEntry -> {
                            // 二级分组:按AB无序组合键
                            return cEntry.getValue().stream()
                                    .collect(Collectors.groupingBy(
                                            obj -> createCompositeKey(obj.getA(), obj.getB())
                                    ));
                        }
                ));

        result.forEach((k, v) -> {
            System.out.println(k + ":" + v.size());
        });
    }

}

输出结果:

无序组合键的详细说明

基本定义​

​无序组合键是指由多个元素(如字段、按键、符号等)组成的标识符,其唯一性由元素的内容决定,而非元素的顺序。这意味着,无论元素的排列顺序如何变化,只要内容相同,组合键的标识作用一致。这一概念广泛应用于数据分组、密码学、快捷键设计等领域。

数学基础 ​:

在组合数学中,无序组合的计算公式为 C(n,m)=m!(n−m)!n!​,其中 n 为元素总数,m 为选取的元素个数(例如从4个元素中选2个,共有6种无序组合)

常见应用场景​
​​(1)数据分组与去重​
  • 数据库/编程中的字段组合 :
    若需根据字段A和B对数据进行分组(例如统计用户行为),但字段顺序不影响分组结果(如A=1、B=2与A=2、B=1视为同一组),可通过以下方式实现:
    • 排序生成唯一键 :将字段值排序后拼接(例如将A和B按升序排列生成键1|2),确保顺序无关
    • 集合类型存储 :使用无序集合(如Java的HashSet)自动处理顺序问题
​​(2)键盘快捷键设计​
  • 组合键的无序触发 :
    某些软件允许用户自定义组合键(如Ctrl+Shift+S与Shift+Ctrl+S触发同一功能),通过检测修饰键(Ctrl、Shift等)是否被按下,而非顺序
    • 实现方式:在事件处理中,通过位运算检查修饰键状态,而非依赖按键顺序
​​(3)密码学与哈希算法​
  • 基于无序组合的密钥生成 :
    在加密算法中,若密钥由多个字符组成,其排列顺序不影响最终加密结果(需特殊设计),可提升密钥的灵活性和抗暴力破解能力。
java 复制代码
// 生成无序组合键(A、B字段顺序无关)
public String generateCompositeKey(String a, String b) {
    String[] values = {a, b};
    Arrays.sort(values); // 排序保证顺序无关
    return values[0] + "|" + values[1]; // 分隔符防止哈希冲突
}

// 使用示例:将对象按A、B字段分组
Map<String, List<MyObject>> groupedObjects = objectList.stream()
    .collect(Collectors.groupingBy(obj -> generateCompositeKey(obj.getA(), obj.getB())));
相关推荐
panxianren18 分钟前
Bun 1.4 的 bun test --parallel 将 4 秒的测试套件缩短到约 1 秒
java·javascript
sunshine22 girl2 小时前
Java学习七 Java 项目实战2-注册业务
java·学习
省钱兄--zs2 小时前
北京24小时自助健身房系统软件开发实战:从架构设计到部署指南
java·数据仓库·spring boot·小程序·需求分析
youdexiang3 小时前
Android录音软件时间关键词检索功能分析
java·人工智能
sunshine22 girl3 小时前
Java学习七 Java 项目实战1-项目创建和主页面搭建
java·开发语言·学习
code2cat3 小时前
Java进阶篇之AtomicStampedReference:引用回到原值,版本戳仍能记住变化
java·cas·并发编程·aba
泡茶喝茶写代码5 小时前
A股量化数据工程:从 REST 接口到策略信号(第 8 篇):成长能力因子:营收与利润增速
java·python·股票数据api·股票数据api接口·股票量化数据api·股票量化数据接口·股票数据api数据
\光辉岁月/6 小时前
7.javase-面向对象
java·开发语言
weixin_531094696 小时前
heap_4内存管理
java·开发语言·算法
余额瞒着我当琳6 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法