如何在特定索引处获取TreeMap的键和值

21

我有一个带有“键和值”对集合的TreeMap。如何在TreeMap的特定索引处获取Key和Value?

编辑:@ALL:谢谢。但是我知道如何使用额外的ArrayList实现它。我只是想知道是否有一种方法可以不使用额外的ArrayList来实现这一点。


2
你为什么想这样做?索引是TreeMap实现内部的。你不应该使用它们。你应该始终只依赖于keys()values()get(key)方法。 - Aleks G
2
你不能通过其他方式来实现这个功能,除了在线性时间内迭代entrySet - Louis Wasserman
我正在开发一个音乐应用程序,需要将专辑名称存储在键中,将专辑ID存储在值中。对于我来说,情况就像是要获取键和值两者。我可以通过使用额外的ArrayList来完成我的任务,但我想简单实现它。 - Dileep Perla
1
你可以使用 keySet() 方法获取键的列表。然后迭代它们以获取特定的一个,并使用 get 方法检索值。 - Aleks G
6个回答

27

如果您确实想使用TreeMap并且需要按位置获取元素,则可以使用以下代码:

key => treemap.keySet().toArray()[0]
value => treemap.get(key); 

或者(如果你只想要值)

treemap.values().toArray()[0]; 

但是我建议您使用迭代器,因为在上述方法中,每次查找都需要创建数组(不太有效率),而且您还应该小心确保索引不超出范围。


我在启动时只创建了这个数组,然后将其作为查找表保留。此外,以下是获取类型化数组的示例 myMap.keySet().toArray(new Integer[0]);。谢谢! - Gene Bo

9

首先,我不确定为什么这里的人们经常关心问题的有效性。有许多情况下,人们认为维护一个已排序的ArrayList是合适的。然而,对于大型列表来说,维护一个已排序的ArrayList是极其低效的。

标准Java(Oracle)源代码中的Entry节点不保留它们的后代树的大小。因此,如果没有进行低效的顺序搜索,就无法通过索引来识别映射中的元素。

我认为这个缺点非常严重,所以我编写了自己的AVL映射,可以有效地按索引获取元素和计算indexOf(E)。实现这一点只需要维护每个Entry的左右分支的大小。 Glazedlists库可能嵌入了可搜索的树,您可以查看一下。


6
你可以将条目集复制到数组列表中,然后通过索引获取所需的条目:

您可以将条目集复制到数组列表中,然后通过索引获取所需的条目:

list=new ArrayList<Map.Entry<K,V>>(treeMap.entrySet());
Map.Entry<K,V>=list.get(index);

但是,a) 复制需要 O(N) 的时间,并且 b) 当 treeMap 发生变化时,列表将变得无效。


2

这可能不是最好的方法,但您可以在特定索引处访问您的键/值。

TreeMap<Object, Object> foo = new TreeMap<Object, Object>();
Object key = foo.keySet().toArray(new Object[foo.size()])[YOUR_INDEX];
Object value = foo.get(key);

1
这可能会有帮助。
TreeMap< String,Integer > ht=new TreeMap<>();

ht.put("12",1);
ht.put("22",2);
ht.put("32",3);
ht.put("42",4);
for(int i=0;i<ht.size();i++)
{
   System.out.println(new Vector(ht.keySet()).get(i));
   System.out.println(new Vector(ht.values()).get(i));
}

-2

这里有另一种从值获取键的选项:

Map<String, String> map = new HashMap<String, String>();
map.put("s1", "s1Val");
map.put("s2", "s2Val");
map.put("s3", "s3Val");

    // ex: "s2Val" -> return "s2"

int index = new ArrayList<String>(map.values()).indexOf("s2Val");
System.out.println(map.keySet().toArray()[index]); // -> return "s2"

与问题OP提出的无关。另外,Map不保证顺序。 - frugalcoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接