55

In java if I am looping over the keySet() of a HashMap, how do I (inside the loop), get the numerical index of that key?

Basically, as I loop through the map, I want to be able to get 0,1,2...I figure this would be cleaner than declaring an int and incrementing with each iteration.

Thanks.

3
  • 3
    What do you need it for? As mentioned in the answers, order in a map is not necessarily constant, it can change when keys get added or removed. Commented Apr 21, 2010 at 19:54
  • 6
    What's even better is that two HashMaps that are equal can still have different orderings. They can do it even if they have the same history of adds/removes (different capacities would do it). Commented Apr 21, 2010 at 20:08
  • stackoverflow.com/questions/18188739/… Commented Sep 23, 2013 at 12:36

11 Answers 11

60

Use LinkedHashMap instead of HashMap It will always return keys in same order (as insertion) when calling keySet()

For more detail, see Class LinkedHashMap

Sign up to request clarification or add additional context in comments.

1 Comment

Order may not be important - we may only need to test for first or last read pair for instance.
50

Not sure if this is any "cleaner", but:

List keys = new ArrayList(map.keySet());
for (int i = 0; i < keys.size(); i++) {
    Object obj = keys.get(i);
    // do stuff here
}

1 Comment

Or similarly: int index = 0; for (Object key : map.keySet()) { Object value = map.get(key); ++index; } // dang formatting
21

The HashMap has no defined ordering of keys.

1 Comment

But LinkedHashMap does
14

If all you are trying to do is get the value out of the hashmap itself, you can do something like the following:

for (Object key : map.keySet()) {
    Object value = map.get(key);
    //TODO: this
}

Or, you can iterate over the entries of a map, if that is what you are interested in:

for (Map.Entry<Object, Object> entry : map.entrySet()) {
    Object key = entry.getKey();
    Object value = entry.getValue();
    //TODO: other cool stuff
}

As a community, we might be able to give you better/more appropriate answers if we had some idea why you needed the indexes or what you thought the indexes could do for you.

Comments

9

You can't - a set is unordered, so there's no index provided. You'll have to declare an int, as you say. Just remember that the next time you call keySet() you won't necessarily get the results in the same order.

2 Comments

If the OP does really want this, it is not hard to write a collection backed by a TreeSet and a Map. That way you can get the results always in the same order. Now as to how to behave when the Map is modified during iteration is up to the OP but a data structure that is a map where the keys are in an ordered set is definitely doable. (btw I'm more commenting on your answer than on the OP's question).
This answer is wrong. Whilst it is true that a set per se is unsorted a LinkedHashMap does indeed keeps the insertion order so on iteration it is possible to get it index based
5

Simply put, hash-based collections aren't indexed so you have to do it manually.

1 Comment

What is the recommended data structure in this case?
4

Posting this as an equally viable alternative to @Binil Thomas's answer - tried to add it as a comment, but was not convinced of the readability of it all.

int index = 0;

for (Object key : map.keySet()) {
   Object value = map.get(key);
   ++index;
}

Probably doesn't help the original question poster since this is the literal situation they were trying to avoid, but may aid others searching for an easy answer.

Comments

3

I was recently learning the concepts behind Hashmap and it was clear that there was no definite ordering of the keys. To iterate you can use:

Hashmap<String,Integer> hs=new Hashmap();
for(Map.Entry<String, Integer> entry : hs.entrySet()){
      String key=entry.getKey();
      int val=entry.getValue();
      //your code block  
  }

Comments

3

I don't know is this what you're looking for

List keys = new ArrayList(map.keySet());
int index = keys.indexOf(element);

Comments

0

You can directly get the keys in Set<K> keySet().

val teamMember = hashMapOf(
            "Coach" to "manager",
            "Player Coach" to "editor",
            "Player" to "member",
            "Supporter" to "readonly"
        )

teamMember.keys.forEachIndexed { index, key ->
   // Here is your key in string 
}

Comments

-2
System.out.println(key.hashCode() & map.size() >> 1);

2 Comments

Can you explain why your code checks whether the [map] key is "j" ? I don't understand how that is related to the posted question.
"j" is the one of the keys in HashMap

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.