map的键值排序问题

前段时间需要用java开发一个公司系统服务的SDK,其中碰到了一个很恶心的问题,在此小记。

需求

我需要将一个对象转成成json字符串,并要求每个字段都是按照字段名升序排序。

已知

fastjson将对象转换成json的时候会将object A 的字段按照名称升序排序。

问题

object A中有个属性是一个对象 B,这个内置对象 B有一个属性是HashMap类型。
1. 我将这个A的json字符串装成object,得到object A
2. 填充object中的部分字段;
3. 将object A转成有序json
至此,问题出现:b对象中的hashMap的顺序为json串中的排列顺序。

一般来说,hashMap会对键值的排序是按照key的哈希值进行排序的。这里本人存在一个误区:认为键值的哈希值的大小顺序和键值的大小顺序是一样的。其实哈希值是的大小无法通过被哈希的值的大小来估计。

解决方法

将hashMap换成TreeMap,并实现自己的Comparator来对键值进行升序排序

### C++ 中 Map 的按键或值排序 #### 按键排序 `std::map` 和 `std::unordered_map` 是 C++ 标准模板库 (STL) 提供的数据结构之一。默认情况下,`std::map` 已经按照键自动进行了升序排列[^1]。 如果需要自定义键的比较方式或者使用其他类型的关联容器(如降序),可以传递一个自定义的比较函数给 map 构造器: ```cpp #include <iostream> #include <map> struct GreaterInt { bool operator()(const int& lhs, const int& rhs) const { return lhs > rhs; } }; int main() { std::map<int, std::string, GreaterInt> myMap; // 插入数据... } ``` 这段代码展示了如何创建一个基于整数键并按降序存储元素的地图。 #### 按值排序 对于按值排序的需求,则不能直接利用 `std::map` 或者其变体来完成此操作,因为这些容器总是依据键来进行内部节点位置调整。为了达到目的,通常有两种方法可以选择: ##### 方法一:复制到向量再排序 一种常见做法是先将所有的 key-value 对拷贝至一对平行数组或是 pair 容器组成的 vector 后,通过调用 sort 函数配合 lambda 表达式指定以 value 值作为主要关键字进行排序: ```cpp #include <algorithm> #include <vector> #include <utility> #include <map> #include <iostream> void sortByValue(const std::map<std::string,int>& m){ // 创建pair<vector>用于保存临时副本 std::vector<std::pair<std::string,int>> vec(m.begin(),m.end()); // 使用sort算法和lambda表达式对vec中的pairs按second成员(即value)从小到大排序 std::sort(vec.begin(), vec.end(), [](const std::pair<std::string,int>& a, const std::pair<std::string,int>& b){return a.second<b.second;} ); // 输出结果 for(auto &p : vec){ std::cout << p.first << ": " << p.second << "\n"; } } // 测试sortByValue功能的小例子 int main(){ std::map<std::string,int> scores = {{"BoB",79},{"LiMin",90},{"ZiLinMi",72}}; sortByValue(scores); } ``` 这种方法简单易懂,适用于大多数场景下的需求[^2]。 ##### 方法二:借助第三方库 Boost.Bimap 实现双向映射 另一种更高效但也稍微复杂一点的方式就是引入额外依赖——Boost 库里的 Bimap 组件。它允许同时维护两个方向上的索引关系,在某些特定应用场景下可能会带来性能优势[^3]。 然而考虑到兼容性和项目规模等因素的影响,除非确实有必要,一般还是推荐采用上述第一种方案更为稳妥可靠。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值