关于java:具有键值映射和排序的数据结构

Data structure that has key-value mapping as well as ordering

我需要一个提供键值映射的数据结构,比如Map,但这也允许我基于(int)索引(例如myKey = myDS.get(index))获取键,而不必迭代数据结构 获得所需索引的密钥。

我想过使用LinkedHashMap,但我没有看到在给定索引处获取密钥的方法。 我错过了LinkedHashMap中的内容吗? 或者我可以使用另一种数据结构吗?

编辑:
这不是重复的。 对另一个问题的正确答案是使用某种SortedMap; 但是,这不是这个问题的正确答案,因为我希望能够通过Integer索引从数据结构中检索Entry,这在任何Java库中都不受支持。


LinkedHashMap提供Map接口的哈希表/双向链表实现。由于它是extends HashMap,它仍然由数组支持,但是还有一个双向链接的Entry对象列表,以确保迭代顺序是可预测的。

所以,基本上它意味着当你迭代遍历地图时:

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

它将按照您添加键的顺序打印,而不是非链接的Map,它不会按插入顺序打印。您无法像所希望的那样访问数组的元素,因为支持哈希的数组不是有序的。只订购了双向链表。

解:

您正在寻找的是来自Apache Commons的LinkedMap。


AFAIK,没有单一的数据结构可以做到这一点。标准Java集合套件中肯定没有一个。

此外LinkedHashMap不是解决方案,因为您无法有效地索引LinkedHashMap

如果要进行基于索引的查找以及基于保持的查找,则解决方案需要是两个数据结构的组合。

  • MapArrayList是更简单的方法,但它有几个问题:
    - 插入和删除ArrayList中的值非常昂贵,除非您在列表的尾端插入/删除。
    - 插入和删除使列表位置不稳定。

  • 如果您想要稳定的索引和可扩展的插入和删除,那么您需要一个Map和一个Map ...以及一种管理(即回收)索引值的方法。

Apache Commons LinkedMap类是一种可能的解决方案,除了它面临插入和删除时索引值不稳定的问题。


如何使用:

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

 mapAsList.get(index);


标准Java Collections API中没有直接DS来提供索引映射。但是,以下应该可以让您实现结果:

1
2
3
4
5
6
7
8
// 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();

您可能仍希望保留地图中与检索分开的数据持久性问题。

更新:
或者按照Steve的建议使用Apache Commons的LinkedMap。


我不相信有这个集合;集合要么基于您想要确切知道元素的位置(列表),要么基于某些键或标准(映射)快速访问;两者都是非常耗费资源的维护。

当然,你可以做出类似这样的事情,正如火箭男孩的回答所暗示的那样,但我猜测它不可能提高效率。