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

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

【问题讨论】:

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

标签: java hashmap


【解决方案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
                

                我希望这对你有用。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2017-01-27
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-12-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-11-19
                  相关资源
                  最近更新 更多