如何使用其键获取LinkedHashMap中键/值的位置

Mat*_*ins 33 java linkedhashmap

嗨,我有一个包含名称/年龄(字符串/整数)对的LinkedHashMap(称为info).我想知道,如果我输入密钥,如何获得键/值的位置.例如,如果我的LinkedHashMap看起来像这样{bob = 12,jeremy = 42,carly = 21}并且我要搜索jeremy,它应该返回1作为它的位置1.我希望我可以使用类似info.getIndex的东西( "杰里米")

小智 28

HashMap通常的实现是无序的Iteration.

LinkedHashMappredictablely订购Iteration(插入顺序),但不公开的List接口和LinkedList(这是反映了按键插入顺序)不跟踪指数本身无论是位置,这是非常的高效的找到索引为好.它LinkedHashMap也不会暴露对内部的引用LinkedList.

实际的"链接列表"行为是特定于实现的.有些人实际上可能会使用LinkedList一些实例,只是 Entry跟踪前一个和下一个,Entry并将其用作实现.不看源,不要假设任何事情.

KeySet包含该键不保证顺序以及由于在继承的后备数据结构用于放置的散列算法HashMap.所以你不能使用它.

在没有编写自己的实现的情况下,执行此操作的唯一方法是Iterator使用镜像LinkedList并使用镜像来保持计数,这对于大型数据集来说非常低效.

你想要的是原始的插入顺序索引位置,你必须镜像KeySet一个类似的东西ArrayList,保持与更新同步,HashMap并用它来寻找位置.创建一个子类HashMap,比如说IndexedHashMap并在ArrayList内部添加.getKeyIndex(<K> key)它并将该委托添加到内部ArrayList .indexOf()可能是解决此问题的最佳方法.

这是做什么LinkedHashMap,但LinkedList镜像KeySet而不是ArrayList.

  • 它保留*订单*但不跟踪*位置*. (4认同)

mar*_*osh 14

int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy")
Run Code Online (Sandbox Code Playgroud)

  • 忽略以上评论。确保了LinkedHashMap的keySet()顺序。/sf/ask/204669951/。 (4认同)
  • Afaik的`keySet()`命令不保证. (3认同)

小智 5

我在这个问题的重复项之一中看到了一条建议

如何根据索引而不是键从 LinkedHashMap 获取值?

我喜欢评论中 @schippi 的伪代码描述的建议。我认为一些可用的 Java 代码可能对其他人有用

import java.util.ArrayList;
import java.util.LinkedHashMap;

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

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    ArrayList<K> al_Index = new ArrayList<K>();

    @Override
    public V put(K key,V val) {
        if (!super.containsKey(key)) al_Index.add(key);
        V returnValue = super.put(key,val);
        return returnValue;
    }

    public V getValueAtIndex(int i){
        return (V) super.get(al_Index.get(i));
    }

    public K getKeyAtIndex(int i) {
        return (K) al_Index.get(i);
    }

    public int getIndexOf(K key) {
        return al_Index.indexOf(key);
    }

}
Run Code Online (Sandbox Code Playgroud)