如何基于索引而非键从LinkedHashMap中获取值?

58

I have

LinkedHashMap<String, List<String>> hMap;

我希望根据索引而不是键获取List<String>

我不想使用迭代。

是否有其他方法根据索引获取值?


2
如果您自己选择这种数据结构,那么它可能不是最适合此任务的。 - Nikolay Kuznetsov
@NikolayKuznetsov:你能给我建议一个应该怎么样的结构吗? - MAC
如果您只通过索引提取元素,则使用ArrayList<String>。 - Nikolay Kuznetsov
1
好的,谢谢。但是现在我正在使用键来获取值。索引不是一个好主意... 再次感谢... - MAC
为什么这个问题关闭了,却没有提及那个被认为是好答案的参考。这里的所有答案都不好。 - mjs
这是我回答的一个问题,无论如何我不能在这里发布,因为这个帖子已经被锁定了:https://dev59.com/pWw05IYBdhLWcg3wuUGY#31749969 - mjs
5个回答

61

您无法基于索引获取 Map 的值,Map 并不按照这种方式工作。一种解决方法是从您的值中创建一个新列表,并基于索引获取该值。

LinkedHashMap<String, List<String>> hMap;
List<List<String>> l = new ArrayList<List<String>>(hMap.values());
l.get(0);

3
如果我想按索引插入值,应该如何实现? - Kanagavelu Sugumar
1
这是我回答的一个问题,无论如何我不能在这里发布,因为这个帖子已经被锁定了:https://dev59.com/pWw05IYBdhLWcg3wuUGY#31749969 - mjs

23
public List<String> getByIndex(LinkedHashMap<String, List<String>> hMap, int index){
   return (List<String>) hMap.values().toArray()[index];
}

5
如果频繁调用 map 中的许多条目,这可能会很昂贵。 - Binkan Salaryman

16

你可能需要考虑使用另一个类来存储数据,或者编写一个扩展 linkedHashMap 的程序。例如:

//this is pseudo code
public class IndexedLinkedHashMap<K,V> extends LinkedHashMap{

HashMap<int,K> index;
int curr = 0;

    @Override
    public void add(K key,V val){
        super.add(key,val);
        index.add(curr++, key);
    }

    public V getindexed(int i){
        return super.get(index.get(i));
    }

}

这似乎是迄今为止最好的方法,但我看不出变量curr的目的。 - Hasen

9
正如Kevin Bowersox所说,这很简单。
List<String> result = (List<String>) hMap.values().toArray()[position];

但需要注意的是,这仍然需要使用.toArray()进行迭代。这是一个简单的语句,我不确定是否有更好性能的语句,但请注意复杂度不是log(n)(例如B*的索引访问),而只是n。 由于LinkedHashMap基于LinkedList,因此没有办法随机访问元素,只能按顺序访问。
将其转换为List是不可避免的恶,因为.toArray()遵循返回Object而不是通用数据类型的古老概念。
尽管这可能不是映射的主要概念,但LinkedHashMap并不仅仅是一个映射。它扩展了HashMap,并且作为扩展类,可以带来支持该类特殊性的其他方法。

1
创建一个新的数组...不太美观 - mjs
1
这是我回答的一个问题,无论如何我不能在这里发布,因为这个帖子已经被锁定了:https://dev59.com/pWw05IYBdhLWcg3wuUGY#31749969 - mjs
@momo 我的帖子只是旨在解释Kevin Bowersox提出的方案无法避免迭代,并且没有这样的方法。通过手动迭代值可以轻松避免创建数组,但当问题是如何在不迭代的情况下完成时,这并不是理想答案。显然,您可以通过创建具有不同索引概念的自己的实现来避免这种情况,但这似乎与问题无关。 - makrom

5

在标准的Java集合API中,没有直接提供索引映射的DS。然而,以下内容可以让您实现此结果:

// 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();

你可能仍然希望将数据持久性的问题与检索分开来处理。更新:或使用Apache Commons的LinkedMap

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