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

Viewed 237822

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?

13 Answers

Kotlin HashMap Answer

You can get key by index. Then get value by key.

val item = HashMap<String, String>() // Dummy HashMap.

val keyByIndex = item.keys.elementAt(0) // Get key by index. I selected "0".

val valueOfElement = item.getValue(keyByIndex) // Get value.

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.

Try this:

myhashmap.entrySet()
           .forEach{
               println(it.getKey())
               println(it.getValue())
           }

or if you want by index

myhashmap.entrySet()[0].getKey()
myhashmap.entrySet()[0].getValue()

myhashmap.entrySet()[1].getKey()
myhashmap.entrySet()[1].getValue()

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'll need to create multiple HashMaps like this for example

Map<String, String> fruitDetails = new HashMap();
fruitDetails.put("Mango", "Mango is a delicious fruit!");
fruitDetails.put("Guava" "Guava is a delicious fruit!");
fruitDetails.put("Pineapple", "Pineapple is a delicious fruit!");
Map<String, String> fruitDetails2 = new HashMap();
fruitDetails2.put("Orange", "Orange is a delicious fruit!");
fruitDetails2.put("Banana" "Banana is a delicious fruit!");
fruitDetails2.put("Apple", "Apple is a delicious fruit!");
// STEP 2: Create a numeric key based HashMap containing fruitDetails so we can access them by index
Map<Integer, Map<String, String>> hashMap = new HashMap();
hashMap.put(0, fruitDetails);
hashMap.put(1, fruitDetails2);
// Now we can successfully access the fruitDetails by index like this
String fruit1 = hashMap.get(0).get("Guava");
String fruit2 = hashMap.get(1).get("Apple");
System.out.println(fruit1); // outputs: Guava is a delicious fruit!
System.out.println(fruit2); // outputs: Apple is a delicious fruit!
Related