是否可以通过其位置从 HashMap 中获取元素?

Posted

技术标签:

【中文标题】是否可以通过其位置从 HashMap 中获取元素?【英文标题】:Is it possible to get element from HashMap by its position? 【发布时间】:2011-07-11 08:40:23 【问题描述】:

如何通过位置从HashMap中检索元素,有可能吗?

【问题讨论】:

“位置”是什么意思? HashMaps 没有顺序,因此它们没有通常的“位置”概念,您可以使用 Vector 之类的东西。 你是指它的插入顺序还是其他顺序? 【参考方案1】:

使用 LinkedHashMap,当您需要按位置检索时,将值转换为 ArrayList。

LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();
/* Populate */
linkedHashMap.put("key0","value0");
linkedHashMap.put("key1","value1");
linkedHashMap.put("key2","value2");
/* Get by position */
int pos = 1;
String value = (new ArrayList<String>(linkedHashMap.values())).get(pos);

【讨论】:

总是需要从 HashMap 实例化一个键的副本?? 这将在我们每次检索值时创建一个新的 ArrayList 对象,从而导致内存泄漏【参考方案2】:

HashMaps 不保留排序:

这个类不保证 地图的顺序;特别是, 它不保证订单 随着时间的推移将保持不变。

看看LinkedHashMap,它保证了可预测的迭代顺序。

【讨论】:

这并不能真正回答问题。下面的其他答案更有用。 尊重,这里引用了直接回答问题的文档 即使随着时间的推移顺序不是恒定的,仍然可以通过给定位置检索成员之一。 我不关注。解释一下? HashMap 链接已损坏/404。【参考方案3】:

如果您想保持将元素添加到地图的顺序,请使用 LinkedHashMap 而不是仅使用 HashMap

这是一种方法,可让您通过地图中的索引获取值:

public Object getElementByIndex(LinkedHashMap map,int index)
    return map.get( (map.keySet().toArray())[ index ] );

【讨论】:

最简单的我必须说...而不是转换所有东西,你只使用键集。很棒【参考方案4】:

如果您出于某种原因必须坚持使用 hashMap,您可以将 keySet 转换为数组并索引数组中的键以获取映射中的值,如下所示:

Object[] keys = map.keySet().toArray();

然后您可以像这样访问地图:

map.get(keys[i]);

【讨论】:

注意 arr[i] 应该改为:keys[i] 好的,我有字符串作为映射键,要获得其中之一,第二部分将是:String myKey = keys[i].toString();【参考方案5】:

使用LinkedHashMap:

Map 接口的哈希表和链表实现,具有可预测的迭代顺序。此实现与 HashMap 的不同之处在于它维护一个双向链表,贯穿其所有条目。

【讨论】:

这将保留订单,但您仍然无法通过索引访问项目。你必须迭代 此链接指向旧版本的 API。我建议链接到 Java 6 或 7 API。【参考方案6】:

使用 LinkedHashMap 并使用此函数。

private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();

这样定义和。

private Entry getEntry(int id)
        Iterator iterator = map.entrySet().iterator();
        int n = 0;
        while(iterator.hasNext())
            Entry entry = (Entry) iterator.next();
            if(n == id)
                return entry;
            
            n ++;
        
        return null;
    

函数可以返回选中的条目。

【讨论】:

【参考方案7】:

默认情况下,java LinkedHasMap 不支持按位置获取值。所以我建议去定制IndexedLinkedHashMap

public class IndexedLinkedHashMap<K, V> extends LinkedHashMap<K, V> 

    private ArrayList<K> keysList = new ArrayList<>();

    public void add(K key, V val) 
        super.put(key, val);
        keysList.add(key);
    

    public void update(K key, V val) 
        super.put(key, val);
    

    public void removeItemByKey(K key) 
        super.remove(key);
        keysList.remove(key);
    

    public void removeItemByIndex(int index) 
        super.remove(keysList.get(index));
        keysList.remove(index);
    

    public V getItemByIndex(int i) 
        return (V) super.get(keysList.get(i));
    

    public int getIndexByKey(K key) 
        return keysList.indexOf(key);
    

那么你就可以把这个自定义的LinkedHasMap用作

IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();

添加价值

indexedLinkedHashMap.add("key1",UserModel);

按索引获取值

indexedLinkedHashMap.getItemByIndex(position);

【讨论】:

你能告诉我如何反转列表吗?就像我们在 Collections.reverse(List) 中使用的一样【参考方案8】:

我假设“位置”是指将元素插入 HashMap 的顺序。在这种情况下,您希望使用 LinkedHashMap。但是 LinkedHashMap 不提供访问器方法;你需要写一个像

public Object getElementAt(LinkedHashMap map, int index) 
    for (Map.Entry entry : map.entrySet()) 
        if (index-- == 0) 
            return entry.value();
        
    
    return null;

【讨论】:

【参考方案9】:

另一种工作方法是将地图值转换为数组,然后检索索引处的元素。使用以下方法在 100 000 个对象的 LinkedHashMap 中通过索引搜索 100 000 个元素的测试运行导致以下结果:

//My answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index)
    return map.values().toArray(new Particle[map.values().size()])[index];
 //68 965 ms

//Syd Lambert's answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index)
    return map.get( (map.keySet().toArray())[ index ] );
 //80 700 ms

总而言之,从 LinkedHashMap 中按索引检索元素似乎是相当繁重的操作。

【讨论】:

【参考方案10】:

HashMap - 以及底层数据结构 - 哈希表,没有位置的概念。与 LinkedList 或 Vector 不同,输入键被转换为存储值的“桶”。这些桶的排序方式在 HashMap 接口之外没有任何意义,因此,您放入 HashMap 中的项目与其他数据结构所期望的顺序不同

【讨论】:

【参考方案11】:

HashMap 没有位置的概念,因此无法按位置获取对象。 Maps 中的对象是通过键设置和获取的。

【讨论】:

【参考方案12】:

您可以使用以下代码获取密钥: String [] keys = (String[]) item.keySet().toArray(new String[0]);

并使用此项目的键获取插入 HashMap 的对象或列表,如下所示: item.get(keys[position]);

【讨论】:

【参考方案13】:

HashMaps 不允许按位置访问,它只知道哈希码,如果它可以计算出键的哈希码,它就可以检索值。 TreeMaps 有一个排序的概念。 Linkedhas 地图会保留他们进入地图的顺序。

【讨论】:

【参考方案14】:

你可以尝试实现类似的东西,看看:

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("juan", 2);
map.put("pedro", 3);
map.put("pablo", 5);
map.put("iphoncio",9)

List<String> indexes = new ArrayList<String>(map.keySet()); // <== Parse

System.out.println(indexes.indexOf("juan"));     // ==> 0
System.out.println(indexes.indexOf("iphoncio"));      // ==> 3

我希望这对你有用。

【讨论】:

以上是关于是否可以通过其位置从 HashMap 中获取元素?的主要内容,如果未能解决你的问题,请参考以下文章

java集合之HashSet

HashMap源码注释翻译

HashMap中确定数组位置为什么要用hash进行扰动

通过位置或索引从Android中的HashMap获取键

是否可以使用淡入淡出将 ui 元素从一个位置移动到另一个位置?

HashMap的扩容机制---resize()