Java HashMap:如何通过索引获取键和值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3973512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 07:47:33  来源:igfitidea点击:

Java HashMap: How to get a key and value by index?

javaiterationhashmap

提问by Derek

I am trying to use a HashMap to map a unique string to a string ArrayList like this:

我正在尝试使用 HashMap 将唯一字符串映射到字符串 ArrayList ,如下所示:

HashMap<String, ArrayList<String>>

Basically, I want to be able to access the keys by number, not by using the key's name. And I want to be able to access said key's value, to iterate over it. I'm imagining something like this:

基本上,我希望能够通过数字访问密钥,而不是使用密钥的名称。而且我希望能够访问所述键的值,并对其进行迭代。我在想象这样的事情:

for(all keys in my hashmap) {
    for(int i=0; i < myhashmap.currentKey.getValue.size(); i++) {
        // do things with the hashmaps elements
    }
}

Is there an easy way to do this?

是否有捷径可寻?

采纳答案by Cameron Skinner

You can iterate over keys by calling map.keySet(), or iterate over the entries by calling map.entrySet(). Iterating over entries will probably be faster.

您可以通过调用迭代键map.keySet(),或通过调用迭代条目map.entrySet()。迭代条目可能会更快。

for (Map.Entry<String, List<String>> entry : map.entrySet()) {
    List<String> list = entry.getValue();
    // Do things with the list
}

If you want to ensure that you iterate over the keys in the same order you inserted them then use a LinkedHashMap.

如果要确保以插入键的相同顺序迭代键,请使用LinkedHashMap.

By the way, I'd recommend changing the declared type of the map to <String, List<String>>. Always best to declare types in terms of the interface rather than the implementation.

顺便说一句,我建议将地图的声明类型更改为<String, List<String>>. 总是最好根据接口而不是实现来声明类型。

回答by Jeff Storey

HashMaps are not ordered, unless you use a LinkedHashMapor SortedMap. In this case, you may want a LinkedHashMap. This will iterate in order of insertion (or in order of last access if you prefer). In this case, it would be

HashMap 不是有序的,除非您使用 aLinkedHashMapSortedMap。在这种情况下,您可能需要一个LinkedHashMap. 这将按照插入的顺序(或者如果您愿意,可以按照上次访问的顺序)进行迭代。在这种情况下,它将是

int index = 0;
for ( Map.Entry<String,ArrayList<String>> e : myHashMap.iterator().entrySet() ) {
    String key = e.getKey();
    ArrayList<String> val = e.getValue();
    index++;
}

There is no direct get(index) in a map because it is an unordered list of key/value pairs. LinkedHashMapis a special case that keeps the order.

映射中没有直接的 get(index) ,因为它是键/值对的无序列表。LinkedHashMap是保持订单的特殊情况。

回答by jjnguy

You can do:

你可以做:

for(String key: hashMap.keySet()){
    for(String value: hashMap.get(key)) {
        // use the value here
    }
}

This will iterate over every key, and then every value of the list associated with each key.

这将迭代每个键,然后迭代与每个键关联的列表的每个值。

回答by kkress

HashMaps don't keep your key/value pairs in a specific order. They are ordered based on the hash that each key's returns from its Object.hashCode() method. You can however iterate over the set of key/value pairs using an iterator with:

HashMaps 不会以特定顺序保存您的键/值对。它们根据每个键从其 Object.hashCode() 方法返回的散列进行排序。但是,您可以使用迭代器迭代一组键/值对:

for (String key : hashmap.keySet()) 
{
    for (list : hashmap.get(key))
    {
        //list.toString()
    }
}

回答by umesh

for (Object key : data.keySet()) {
    String lKey = (String) key;
    List<String> list = data.get(key);
}

回答by dumonderic

Here is the general solution if you really only want the first key's value

如果您真的只想要第一个键的值,这是通用解决方案

Object firstKey = myHashMap.keySet().toArray()[0];
Object valueForFirstKey = myHashMap.get(firstKey);

回答by fspinnenhirn

If you don't care about the actual key, a concise way to iterate over allthe Map's values would be to use its values()method

如果你不关心实际的键,迭代所有Map 值的简洁方法是使用它的values()方法

Map<String, List<String>> myMap;

for ( List<String> stringList : myMap.values() ) {
    for ( String myString : stringList ) {
        // process the string here
    }
}

The values()method is part of the Map interface and returns a Collection view of the values in the map.

values()方法是 Map 接口的一部分,并返回地图中值的 Collection 视图。

回答by Ayaz Alifov

A solution is already selected. However, I post this solution for those who want to use an alternative approach:

已选择解决方案。但是,我为那些想要使用替代方法的人发布了这个解决方案:

// use LinkedHashMap if you want to read values from the hashmap in the same order as you put them into it
private ArrayList<String> getMapValueAt(LinkedHashMap<String, ArrayList<String>> hashMap, int index)
{
    Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>) hashMap.entrySet().toArray()[index];
    return entry.getValue();
}

回答by Makwana Mehul

You can use Kotlin extension function

您可以使用 Kotlin 扩展功能

fun LinkedHashMap<String, String>.getKeyByPosition(position: Int) =
        this.keys.toTypedArray()[position]


fun LinkedHashMap<String, String>.getValueByPosition(position: Int) =
        this.values.toTypedArray()[position]

回答by Benjavo

I came across the same problem, read a couple of answers from different related questions and came up with my own class.

我遇到了同样的问题,从不同的相关问题中阅读了几个答案,并提出了我自己的课程。

public class IndexableMap<K, V> extends HashMap<K, V> {

    private LinkedList<K> keyList = new LinkedList<>();

    @Override
    public V put(K key, V value) {
        if (!keyList.contains(key))
            keyList.add(key);
        return super.put(key, value);
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
            put(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public void clear() {
        keyList.clear();
        super.clear();
    }

    public List<K> getKeys() {
        return keyList;
    }

    public int getKeyIndex(K key) {
        return keyList.indexOf(key);
    }

    public K getKeyAt(int index) {
        if (keyList.size() > index)
            return keyList.get(index);
        return null;
    }

    public V getValueAt(int index) {
        K key = getKeyAt(index);
        if (key != null)
            return get(key);
        return null;
    }
}

Example (types are differing from OPs question just for clarity):

示例(为了清楚起见,类型与 OP 问题不同):

Map<String, Double> myMap = new IndexableMap<>();

List<String> keys = myMap.getKeys();
int keyIndex = myMap.getKeyIndex("keyString");
String key = myMap.getKeyAt(2);
Double value myMap.getValueAt(2);

Keep in mind that it does not override any of the complex methods, so you will need to do this on your own if you want to reliably access one of these.

请记住,它不会覆盖任何复杂的方法,因此如果您想可靠地访问其中之一,则需要自己执行此操作。

Edit: I made a change to the putAll() method, because the old one had a rare chance to cause HashMap and LinkedList being in different states.

编辑:我对 putAll() 方法进行了更改,因为旧方法很少有机会导致 HashMap 和 LinkedList 处于不同状态。