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

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

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?

This question is related to java iteration hashmap

The answer is


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:

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

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):

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.


You can use Kotlin extension function

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


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

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.


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

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

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

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.


HashMaps are not ordered, unless you use a LinkedHashMap or 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

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. LinkedHashMap is a special case that keeps the order.


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

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to iteration

Is there a way in Pandas to use previous row value in dataframe.apply when previous value is also calculated in the apply? How to loop over grouped Pandas dataframe? How to iterate through a list of dictionaries in Jinja template? How to iterate through an ArrayList of Objects of ArrayList of Objects? Ways to iterate over a list in Java Python list iterator behavior and next(iterator) How to loop through an array containing objects and access their properties recursion versus iteration What is the perfect counterpart in Python for "while not EOF" How to iterate over a JavaScript object?

Examples related to hashmap

How to split a string in two and store it in a field Printing a java map Map<String, Object> - How? Hashmap with Streams in Java 8 Streams to collect value of Map How to convert String into Hashmap in java Convert object array to hash map, indexed by an attribute value of the Object HashMap - getting First Key value The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files Sort Go map values by keys Print all key/value pairs in a Java ConcurrentHashMap creating Hashmap from a JSON String