我有一个Java程序,我想将它转换为C ++。因此,Java代码中使用了Linkedhashmap
数据结构,我想将其转换为C ++。在C ++中是否有LinkedHashmap
的等效数据类型?
我尝试使用std::unordered_map
,但是,它不会保持插入的顺序。
答案 0 :(得分:15)
C ++不提供具有模仿Java LinkedHashMap<K,V>
的行为的集合模板,因此您需要与映射分开维护订单。
这可以通过将数据保存在std::list<std::pair<K,V>>
中,并保留单独的std::unordered_map<k,std::list::iterator<std::pair<K,V>>>
地图,以便按键快速查找项目来实现:
std::prev(list.end())
。std::list<std::pair<K,V>>
。答案 1 :(得分:2)
密钥迭代的插入顺序契约可以通过用于log(n)性能的平衡树来实现。这比维护列表中的键更好,因为项目删除需要n个查找时间。我的口头禅从来没有把你在列表中查找的内容。如果不必排序,请使用哈希。如果应该排序,请使用平衡树。如果您要做的就是迭代,那么列表就可以了。
在c ++中,这将是std::map
,其中键是项引用,值是插入顺序,键是使用红黑树排序的。请参阅:Is there a sorted container in STL
答案 2 :(得分:0)
无序映射或用C ++内置的任何其他STL方法不能给出与LinkedHashMap相同的顺序,尽管您可以维护插入的顺序并使用维护的顺序访问unordered_map。
下面的图像只是为了显示unordered_map的行为。它没有订单。
Map是RB树,如果使用迭代器,它会给出排序顺序。
因此没有针对此问题的具体解决方案。
答案 3 :(得分:0)
这是我的方法:
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;