简体   繁体   English

具有键值映射和排序的数据结构

[英]Data structure that has key-value mapping as well as ordering

I need a data structure that provides key-value mappings, like a Map , but that also allows me to fetch the key based on an (int) index (eg myKey = myDS.get(index) ), without having to iterate over the data structure to get the key at the desired index. 我需要一个提供键值映射的数据结构,比如Map ,但这也允许我基于(int)索引(例如myKey = myDS.get(index) )获取键,而不必迭代数据结构,以获得所需索引的键。

I thought of using LinkedHashMap , but I don't see a way to get the key at a given index. 我想过使用LinkedHashMap ,但我没有看到在给定索引处获取密钥的方法。 Am I missing something in LinkedHashMap ? 我在LinkedHashMap遗漏了什么? Or is there another data structure I can use? 或者我可以使用另一种数据结构吗?

EDIT : 编辑
This is not a duplicate. 不是重复的。 The correct answer to the other question is to use some sort of SortedMap ; 另一个问题的正确答案是使用某种SortedMap ; however, that is not the correct answer to this question, since I'd like to be able to retrieve an Entry from the data structure via an Integer index, which is not supported in any Java library. 但是,这不是这个问题的正确答案,因为我希望能够通过Integer索引从数据结构中检索一个Entry ,这在任何Java库中都不受支持。

LinkedHashMap provides a hash table/doubly linked list implementation of the Map interface. LinkedHashMap提供Map接口的哈希表/双向链表实现。 Since it extends HashMap , it's still backed by an array, but there is also a doubly-linked list of Entry objects to ensure that the iteration order is predictable. 由于它extends HashMap ,它仍然由数组支持,但是还有一个双向链接的Entry对象列表,以确保迭代顺序是可预测的。

So, basically what it means is that when you iterate through the map like so: 所以,基本上它意味着当你迭代遍历地图时:

for (Map.Entry<keyType,valueType>> entry : linkedHashMap.entrySet())
{
   System.out.println("Key: " + entry.getKey().toString() + 
                     " Value: " + entry.getValue.toString());
}

it will print in the order that you added the keys, as opposed to a non-linked Map, which will not print in insertion order . 它将按照您添加键的顺序打印,而不是非链接的Map,它不会插入顺序打印。 You cannot access the elements of the array like you want to, because the array that backs the hash is not in order . 无法像所希望的那样访问数组的元素,因为支持哈希的数组不是有序的 Only the doubly linked list is ordered. 只订购了双向链表。

Solution: 解:

What you are looking for is a LinkedMap from Apache Commons. 您正在寻找的是来自Apache Commons的LinkedMap

AFAIK, there is no single data structure that will do this. AFAIK,没有单一的数据结构可以做到这一点。 There is certainly not one in the standard Java collection suite. 标准Java集合套件中肯定没有一个。

Also LinkedHashMap is not the solution because you cannot efficiently index a LinkedHashMap . LinkedHashMap也不是解决方案,因为您无法有效地索引LinkedHashMap

If you want to do index-based lookup as well as keep-based lookup, solution needs to be a combination of two data structures. 如果要进行基于索引的查找以及基于保持的查找,则解决方案需要是两个数据结构的组合。

  • A Map<Key, Value> and an ArrayList<Value> is the simpler approach, but it has a couple of problems: - Insertion and deletion of values from the ArrayList is expensive, unless you are inserting / deleting at the tail end of the list. Map<Key, Value>ArrayList<Value>是更简单的方法,但它有几个问题: - 从ArrayList插入和删除值是昂贵的,除非你在尾端插入/删除名单。 - Insertion and deletion makes the list positions unstable,. - 插入和删除使列表位置不稳定。

  • If you want stable indexes and scalable insertion and deletion, then you need a Map<Key, Value> and a Map<Integer, Value> ... and a way to manage (ie recycle) the index values. 如果您想要稳定的索引和可扩展的插入和删除,那么您需要Map<Key, Value>Map<Integer, Value> ...以及管理(即回收)索引值的方法。


The Apache Commons LinkedMap class is a possible solution, except that it suffers from the problem that index values are not stable in the face of insertions and deletions. Apache Commons LinkedMap类是一种可能的解决方案,除了它存在索引值在插入和删除时不稳定的问题。

How about using: 如何使用:

Map<String, String> map = new LinkedHashMap<String, String>();
List<Entry<String, String>> mapAsList = new ArrayList<Map.Entry<String,String>>(map.entrySet());

 mapAsList.get(index);

I do not believe there is a collection for this; 我不相信有这个集合; collections are either based on the idea that you want to know exactly where an element is (lists) or that you want quick access based on some key or criteria (maps); 集合要么基于您想要确切知道元素的位置(列表), 要么基于某些键或标准(映射)快速访问; doing both would be very resource-intensive to maintain. 两者都是非常耗费资源的维护。

Of course, you can make something like this, as rocketboy's answer suggests, but I'm guessing it's not really possible to make efficient. 当然,你可以做出类似这样的事情,正如火箭男孩的回答所暗示的那样,但我猜测它不可能提高效率。

There is no direct DS in the standard Java Collections API to provide a indexed map. 标准Java Collections API中没有直接DS来提供索引映射。 However, the following should let you achieve the result: 但是,以下应该可以让您实现结果:

// An ordered map
Map<K, V> map = new LinkedHashMap<K, V>();
// To create indexed list, copy the references into an ArrayList (backed by an array)
List<Entry<K, V>> indexedList = new ArrayList<Map.Entry<K, V>>(map.entrySet());
// Get the i'th term
<Map.Entry<K,V>> entry = indexedList.get(index);
K key = entry.getKey();
V value = entry.getValue();

You might still want to retain the concerns of data persistence in the map separate from the retrieval. 您可能仍希望保留地图中与检索分开的数据持久性问题。

Update: Or use LinkedMap from Apache Commons as suggested by Steve. 更新:或者按照Steve的建议使用Apache Commons中的LinkedMap。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我应该使用哪种数据结构来支持键值映射,反向迭代和插入排序? - Which data structure should I use to support key-value mappings, reverse iteration and insertion ordering? 用于存储类型的键值对的数据结构 <String, String> ? 一把钥匙有很多价值 - What data structure to use to store key-value pairs of type <String, String>? One key has many values 哪种数据结构对键值对有效? - which data structure is efficient for key-value pair? 通过Spring-Data在Elasticsearch中存储键值结构 - Store Key-Value structure in Elasticsearch via Spring-Data 快速静态键值映射 - fast static key-value mapping Spring 数据 Elasticsearch 动态映射。 Map 属性作为键值? - Spring Data Elasticsearch dynamic mapping. Map property as key-value? Java Hashmap就像数据结构一样,用于锁定键值对,然后在put上解锁 - 用于爬虫礼貌 - Java Hashmap like data structure that locks the key-value pair on get and unlocks back on put - for crawler politeness BeanIO定长记录中的键值映射 - Key-value mapping in BeanIO fixed-length record 在 Springboot Java 中维护键值映射对的最佳方法 - Best way to maintain key-value mapping pairs in Springboot Java GAE Datastore 上的键值对数据? - Key-Value data on GAE Datastore?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM