go语言实现类似java中的LinkedHashMap

本文介绍了如何使用go-ordered-json库解决Go语言中map的无序问题,通过OrderedObject类型确保json序列化时key的顺序保持,包括json转Map及Map转json的示例和相关背景信息。
摘要由CSDN通过智能技术生成

想实现功能

json 转 map 时按照json的顺序给 map 赋值并保持 map 中 key 的顺序
map 转 json 时按照 map 中 key 的顺序转为 json 字符串

参考文章

https://www.haoyizebo.com/posts/7a38ee65/
https://github.com/virtuald/go-ordered-json

go语言内置的 map 是一个普通的 hashmap,是无序的,每次遍历 map 时都会有不同的顺序
go语言自带的 json 包序列化 map 转 json 字符串时,不完全是无序的,是保持一种特定的规则排序,并且不能改变,这种规则就是按照 key 的ascii码值排序

实现方法

如上面文章介绍,之前有人试图给 Go 标准库提交过相关的代码,但是被拒绝了((沮丧脸) 详情可见 7930: encoding/json: Optionally preserve the key order of JSON objects ),不过在 GitHub 上还是能找到相关的代码的:go-ordered-json,我们就可以用使用这个库来完成。

具体的使用方法就是使用"github.com/virtuald/go-ordered-json"包中的json.OrderedObject 类型取代 map 类型,并使用上面包提供的序列化与序列化方法

说明:这个包的代码有一些不规范的地方,就是引入的包名和代码文件中的package名字是不一样的,文件中的package是json,然而引入的包名是github.com/virtuald/go-ordered-json,因些使用起来会稍感别扭,当然为什么这样就不得面知了,不过好用就行

示例代码:

package main

import (
    "fmt"
    "github.com/virtuald/go-ordered-json"
)

func main() {
    jsonString := `{
    "b": "2",
    "a": "1",
    "c": "3"
}`

    oo := json.OrderedObject{}
    err := json.Unmarshal([]byte(jsonString), &oo)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%+v", oo)
}
在C++标准库并没有直接提供类似Java的`LinkedHashMap`的数据结构,它是Java集合框架的一部分,用于维护插入顺序并支持高效的迭代。然而,你可以使用STL(Standard Template Library)的关联容器`std::unordered_map`或`std::map`来模拟部分功能。 `std::unordered_map`提供了快速查找(平均时间复杂度为O(1)),但没有保持元素的插入顺序。如果你需要保留插入顺序,可以考虑使用`std::map`,但是查找速度可能会稍慢一些(时间复杂度为O(log n)`。 如果你想自己实现一个更接近LinkedHashMap的功能,你可以创建一个自定义模板类,包含一个双向链表(`std::list`)作为底层存储,并有一个映射(`std::unordered_map`或`std::map`)来处理键值对。每当添加、删除或访问元素时,更新链表的顺序。 以下是一个简单的自定义`LinkedHashMap`概念示例: ```cpp template <typename Key, typename Value> class LinkedHashMap { private: std::list<std::pair<Key, Value>> ordered_list; std::unordered_map<Key, std::list<std::pair<Key, Value>>::iterator> key_to_iterator; public: // 添加元素,同时保持链表和映射同步 void insert(const Key& key, const Value& value) { ordered_list.push_back({key, value}); key_to_iterator[key] = ordered_list.end() - 1; } // 删除元素,同样同步链表和映射 void remove(const Key& key) { auto it = key_to_iterator.find(key); if (it != key_to_iterator.end()) { ordered_list.erase(it->second); key_to_iterator.erase(it); } } // 其他方法如查找、迭代等 }; ``` 请注意,这个例子只是一个简化的版本,实际使用时可能需要处理更多细节,比如迭代器失效等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值