利用 Map 集合的 containsKey 方法,实现对象数组的去重以及重复对象的字段值累加

博客介绍了如何利用Map集合的containsKey方法处理对象数组,实现去重并累加相同对象的字段值。通过创建Person实体类,设置初始数据,重写equals和hashCode方法,然后遍历数组,使用containsKey判断并累加金额,最后将Map转为List。总结中提到,虽然一开始走了弯路,但最终找到解决方案,认识到需要拓宽知识面和灵活思考问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 前言

公司的项目又加了一个新需求,打印发票增加详细收费方式以及每种收费收费金额。一开始没把它当回事,想着服务端返回的支付信息里包含着各种支付记录,在打印模块里将接收到的支付信息 List 遍历一下,然后打印出来就好了。

后来做的时候发现,是我想得简单了。

因为服务端返回的支付信息是按照每笔交易记录返回的,即如果支付总额为20元,如果使用者支付了两次10元完成的支付,那么服务端存储的这笔交易的支付信息就为两次10元的支付记录。具体返回的 json 串示例如下:

    "***INFOS\": [
        {
            \"***NAME\": \"现金收费\",
            \"***ACCOUNT\": \"7.0\",
            \"***NUM\": \"1000000576\"
        },
        {
            \"***NAME\": \"现金收费\",
            \"***ACCOUNT\": \"3.0\",
            \"***NUM\": \"1000000576\"
        },
        {
            \"***NAME\": \"现金收费\",
            \"***ACCOUNT\": \"5.0\",
            \"***NUM\": \"1000000576\"
        },
        {
            \"***NAME\": \"微信收费\",
            \"***ACCOUNT\": \"15.0\",
            \"***NUM\": \"1000000576\"
        },
        {
            \"***NAME\": \"微信收费\",
            \"***ACCOUNT\": \"8.0\",
            \"***NUM\": \"1000000576\"
        }
    ]

可以看到,此次交易总额为38元,然后使用者分了5次完成的支付。如果我什么也不处理就开始遍历打印的话,打出的发票信息上显示的详细支付信息就是3条现金支付记录,和2条微信支付记录,只是钱数不同而已。这样是肯定不行的,所以这里要处理一下数据。

2. 思路

思路其实很简单,就是把 List 中的相同支付方式去重,然后将每笔支付金额相加,得出的总额算作是这种支付方式的支付钱数。即前文中那笔示例交易,处理后应该为:

    "***INFOS\": [
        {
            \"***NAME\": \"现金收费\",
            \"***ACCOUNT\": \"15.0\",
            \"***NUM\": \"1000000576\"
        },
        {
            \"***NAME\": \"微信收费\",
            \"***ACCOUNT\": \"23.0\",
            \"***NUM\": \"1000000576\"
        }
    ]

好了,思路清晰了,就去完成它吧。

3. 实现

实现的部分在新建的示例工程中完成。

创建一个实体类对象:

    public class Person {
   
   

        private String mName;
        private String mMoney;

        public Person(String pName, String pMoney) {
<think>好的,我需要解答用户关于C++中map容器自动原理的问题。首先,我得回忆一下map的基本特性。根据引用[2],map属于关联式容器,存储的是键对,并且数据检索效率高。自动应该和键的唯一性有关。 接下来,我需要确定map的数据结构。通常,C++的map是红黑树实现的,这是一种自平衡的二叉搜索树。红黑树的有序性保证了插入时的查找效率,而节点的唯一性则由键的比较决定。 用户提到自动,应该是指插入相同键的元素时,map会自动保留一个。这是因为红黑树在插入新节点时,会先查找是否存在相同的键。如果存在,根据map的设计,会忽略新插入的键或者覆盖,具体取决于插入方法。比如使用insert方法会保留原有键,而使用operator[]可能会覆盖。 需要解释键对的比较机制,引用[1]中的示例代码提到了key_eq()函数,这可能涉及比较器。在map中,默认使用std::less来比较键,确保有序性。当插入一个已存在的键时,比较器会判断相等,从而阻止重复插入。 可能还需要提到multimap和unordered_map的区别,但用户问的是map,所以点放在红黑树和键的唯一性上。总结时,数据结构的有序性和比较机制共同实现了自动的功能。 现在要组织这些点,用中文清晰回答,确保符合格式要求,比如行内公式用$,独立公式用$$,并生成相关问题。同时检查引用是否正确添加,比如引用[2]提到键对和关联容器的效率,引用[1]中的代码示例虽然关于unordered_multimap,但可以辅助说明比较器的使用。</think>### C++ map容器自动原理 C++中的`std::map`是一种关联容器,其自动的特性源于其底层数据结构和键的唯一性设计。以下是具体原理: 1. **基于红黑树的实现** `std::map`通常以红黑树(Red-Black Tree)作为底层数据结构[^2]。红黑树是一种自平衡的二叉搜索树,具有以下特性: - 每个节点的键唯一 - 插入新节点时会通过比较键自动维护有序性 - 插入重复时,树会自动拒绝或覆盖(取决于插入方式) 2. **键的唯一性约束** `std::map`要求所有键必须唯一。插入操作(如`insert`)会先通过键的比较器(默认`std::less<Key>`)查找是否存在相同键: - 若存在,则保留原有键对,新被忽略 - 若不存在,则构造新节点插入树中 例如,以下代码会保留第一个插入的键: ```cpp std::map<int, string> m; m.insert({1, "a"}); // 插入成功 m.insert({1, "b"}); // 插入失败,键1已存在 ``` 3. **比较器的核心作用** 键的唯一性通过比较器判断。当插入元素时,红黑树会调用`key_compare`函数(如`operator<`)遍历树节点: $$ \text{若} \ a < b \ \text{为假且} \ b < a \ \text{为假,则判定} \ a = b $$ 这一机制确保了键的唯一性逻辑[^1]。 4. **与multimap的对比** 与允许重复键的`std::multimap`不同,`std::map`在模板定义中已通过类型参数强制约束键唯一性。两者的底层结构类似,但插入逻辑不同。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值