0

Why is there no map.get(index) in a Java HashMap ?

To access the first key's value in a HashMap I have to put the keys into a list then list.get(0) and then pass that to map.get(list.get(0)); I feel this is clumsy. Why is this so?

What would be the right approach to access, say, the "first or second element" from a HashMap?

(please do not suggest "convert HashMap to LinkedHashMap and access it by Iterating).

4
  • 9
    A Hashmap is not a sorted data structure. You should never use it if you want to access items in a sorted way, since concepts like "first element" are alien to a Hashmap. Commented Jun 17, 2014 at 12:29
  • I'm curious... Why do you want to do this? Commented Jun 17, 2014 at 12:31
  • in my code logic, i will be adding key with the values and after that logic, i am passing map and need to get first element to check some functionality..right now i am doing it by using list as i explained in the post Commented Jun 17, 2014 at 18:41
  • There is no right approach to access the n-th element from a HashMap, because the concept of "index" is completely meaningless for a HashMap. The currently highest voted answer (and comment) explains this quite clearly. What you are asking for is impossible. If you want a map that you can navigate, use an implementation of NavigableMap. In addition, what exactly do you mean by "first"? First element you put in to the map? First element in a sorted map? Commented Jun 17, 2014 at 19:18

7 Answers 7

4

Asking for "the first elemet" of a HashMap does not make sense, because the order can (and will, in general) change as elements are added and removed.

This is explained in the documentation for HashMap

"... makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time."

You can test it with the following experiment:

import java.util.HashMap;
public class M {
public static void main(String[] args) {
   HashMap<String, Integer> m = new HashMap<String, Integer>();
   for (int i=1, p=1; i<100000; i++) {
      m.put(""+i, i);
      if (i == p) { 
         p <<= 1;  // keys are reordered at power-of-two multiples
         System.out.println("at " + p + ": first is now " 
            + m.keySet().iterator().next());
      }
   }
}
}    

The output is (JDK 1.7):

at 2: first is now 1
at 4: first is now 2
at 8: first is now 3
at 16: first is now 3
at 32: first is now 15
at 64: first is now 19
at 128: first is now 35
at 256: first is now 35
at 512: first is now 35
at 1024: first is now 338
at 2048: first is now 338
at 4096: first is now 1411
at 8192: first is now 3280
at 16384: first is now 6873
at 32768: first is now 10997
at 65536: first is now 10997
at 131072: first is now 10997

If you require repeatable ordering (= iterating over elements will always give you their order of insertion), you can always use a LinkedHashMap. Beware that they require a bit more memory and are slightly slower than the standard variety.

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

Comments

2

HashMap is not ordered: index i in a HashMap does not mean anything.

You can only access it with a key.

Comments

1

See http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html:

"This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time."

So there is no first or second element ...

Comments

0

If the order of elements is important to you, you should not be using Hashmap. Hashmap is not an ordered data structure.

Comments

0

A map(ping) by definition does not have an ordering, either on the keys or values, that's why.

If you have a look at the JavaDoc, you will see that eg. the keys are returned as a Set, not a List.

I suppose you could define a special map, which retained eg. insertion order, but that would not conform to the contract in the Java version, which specifically states that it

"... makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time."

Cheers,

Comments

0

Not sure if your looking for this: Iterate to find a Map entry at an index? or something else

List<Entry<String,Foo>> randAccess = new ArrayList<Entry<String,Foo>>(foos.entrySet());
randAccess.get(N)

2 Comments

That requires making a copy of all keys in the map, which is somewhat expensive.
Also, the OP explicitly said that converting to list-of-keys was out.
0

HashMap internally uses Set. Order is not preserved. SO you can not access it using index.

1 Comment

Internally uses Set? Since when?

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.