是否可以通过HashMap的位置获取元素?


99

如何从HashMap的位置检索元素,这有可能吗?


11
“位置”是什么意思?HashMap没有排序,因此它们没有通常使用Vector之类的“位置”概念。

1
您是指其插入顺序还是其他一些顺序?
Mark Elliot

Answers:


94

HashMaps不保留排序:

此类无法保证地图的顺序。特别是,它不能保证顺序会随着时间的推移保持恒定。

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


16
这并不能真正回答问题。下面的其他答案更有用。
forresthopkinsa

6
相对而言,这引用了直接回答问题的文档
Wayne

1
即使顺序不是随时间变化的,也仍然有可能通过给定位置检索成员之一。
初学者

我不懂 说明?
韦恩

HashMap链接已断开/ 404。
拉夫

109

使用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);

2
始终需要从HashMap实例化密钥副本吗?
理查德

每当我们检索值时,这都会创建一个新的ArrayList对象,从而导致内存泄漏
NullByte08

48

如果要维持将元素添加到地图的顺序,请使用LinkedHashMap而不是just HashMap

这是一种允许您通过映射中的索引获取值的方法:

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

1
我必须说的最简单...您仅使用键集而不是转换所有东西。精湛
kirtan403 '16

19

如果由于某种原因必须坚持使用hashMap,则可以将keySet转换为数组,然后对数组中的键进行索引以获取映射中的值,如下所示:

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

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

map.get(keys[i]);

请注意,arr [i]应该更改为:keys [i]
Mohsen Abasi

好吧,我有Strings作为映射键,要获取其中之一,第二部分将是:String myKey = keys[i].toString();
Orici

12

用途LinkedHashMap

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


27
这样可以保留订单,但是您仍然无法通过其索引访问项目。你必须遍历
Bozho

该链接是API的旧版本。我建议链接到Java 6或7 API。
jzd 2011年

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;
    }

该函数可以返回所选的条目。


3

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

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

3

另一种工作方法是将映射值转换为数组,然后在索引处检索元素。使用以下方法在10万个对象的LinkedHashMap中通过索引搜索对10万个元素进行测试运行,得出以下结果:

//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中按索引检索元素似乎是很繁重的操作。


2

HashMap-和基础数据结构-哈希表没有位置的概念。与LinkedList或Vector不同,输入键被转换为存储值的“存储桶”。这些存储区的排序方式在HashMap界面之外并不合理,因此,您放入HashMap中的项目与其他数据结构所期望的顺序不一样


2

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


2

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

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


2

默认情况下,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);

1

HashMaps不允许按位置访问,它仅了解哈希码,并且可以计算键的哈希码,并且可以检索值。TreeMap具有排序的概念。链接的地图保留其进入地图的顺序。


0

您可以尝试实现类似的方法,请看:

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

希望这对您有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.