等效于C++中的LinkedHashmap

equivalent LinkedHashmap in C++?

本文关键字:中的 LinkedHashmap C++      更新时间:2023-10-16

我有一个Java程序,我想把它转换成C++。因此,Java 代码中使用了一个Linkedhashmap数据结构,我想将其转换为C++。C++中是否有等效的LinkedHashmap数据类型?

我尝试使用std::unordered_map,但是,它不保持插入的顺序。

C++没有

提供具有模仿Java LinkedHashMap<K,V>行为的集合模板,因此您需要将顺序与映射分开维护。

这可以通过以下方式实现:将数据保存在std::list<std::pair<K,V>>中,并保留单独的std::unordered_map<K,std::list<std::pair<K,V>>::iterator>映射,以便按键快速查找项目:

  • 添加项目时,将相应的键/值对添加到列表末尾,并将键映射到迭代器std::prev(list.end())
  • 按键删除项时,查找其迭代器,将其从列表中删除,然后删除映射。
  • 替换
  • 项目时,首先从无序列图中查找列表迭代器,然后用新的键值对替换其内容。
  • 在迭代值时,只需迭代std::list<std::pair<K,V>> .

密钥迭代的广告顺序协定可以通过平衡树来实现 log(n( 性能。 这比在列表中维护键要好,因为删除项目需要 n 个查找时间。 我的口头禅是永远不要把你查找的东西放在列表中。 如果不必对其进行排序,请使用哈希。 如果要对其进行排序,请使用平衡树。 如果你要做的只是迭代,那么列表就可以了。在 c++ 中,这将std::map键是项目引用,值是插入顺序,键使用红黑树排序。 请参阅:STL

map<TKey, set<MyClass<K1,K2>, greater<MyClass<K1, K2>>>> _objects; // set ordered by timestamp. Does not guarantee uniqueness based on K1 and K2. map<TKey, map<K2, typename set<MyClass<K1, K2>, greater<MyClass<K1, K2>>>::iterator>> _objectsMap; // Used to locate object in _objects

要添加对象id

    if (_objectsMap[userId].find(id) == _objectsMap[userId].end())
       _objectsMap[userId][id] = _objects[userId].emplace(userId, id).first;

要擦除对象id

   if (_objectsMap[userId].find(id) != _objectsMap[userId].end()) {
       _objects[userId].erase(_objectsMap[userId][id]);
       _objectsMap[userId].erase(id);
   }

要检索,请说出列表中从特定对象开始的最新size对象id

    vector<K2> result;
    if (_objectsMap[userId].find(id) != _objectsMap[userId].end() && _objectsMap[userId][id] != _objects[userId].begin()) {
        set<MyClass<K2, K2>, greater<MyClass<K1, K2>>>::iterator start = _objects[userId].begin(), end = _objectsMap[userId][id];
        size_t counts = distance(_objects[userId].begin(), _objectsMap[userId][id]);
        if (counts > size)
            advance(start, counts - size);        
        transform(start,
            end,
            back_inserter(result),
            [](const MyClass<K1, K2>& obj) { return obj.ID(); });
    }
    return result;