is the Java HashMap keySet() iteration order consistent?

I understand that the Set returned from a Map's keySet() method does not guarantee any particular order.

My question is, does it guarantee the same order over multiple iterations. For example

Map<K,V> map = getMap();

for( K k : map.keySet() )
{
}

...

for( K k : map.keySet() )
{
}

In the above code, assuming that the map is not modified, will the iteration over the keySets be in the same order. Using Sun's jdk15 it does iterate in the same order, but before I depend on this behavior, I'd like to know if all JDKs will do the same.

EDIT

I see from the answers that I cannot depend on it. Too bad. I was hoping to get away with not having to build some new Collection to guarantee my ordering. My code needed to iterate through, do some logic, and then iterate through again with the same ordering. I'll just create a new ArrayList from the keySet which will guarantee order.


Solution 1:

You can use a LinkedHashMap if you want a HashMap whose iteration order does not change.

Moreover you should always use it if you iterate through the collection. Iterating over HashMap's entrySet or keySet is much slower than over LinkedHashMap's.

Solution 2:

If it is not stated to be guaranteed in the API documentation, then you shouldn't depend on it. The behavior might even change from one release of the JDK to the next, even from the same vendor's JDK.

You could easily get the set and then just sort it yourself, right?

Solution 3:

Map is only an interface (rather than a class), which means that the underlying class that implements it (and there are many) could behave differently, and the contract for keySet() in the API does not indicate that consistent iteration is required.

If you are looking at a specific class that implements Map (HashMap, LinkedHashMap, TreeMap, etc) then you could see how it implements the keySet() function to determine what the behaviour would be by checking out the source, you'd have to really take a close look at the algorithm to see if the property you are looking for is preserved (that is, consistent iteration order when the map has not had any insertions/removals between iterations). The source for HashMap, for example, is here (open JDK 6): http://www.docjar.com/html/api/java/util/HashMap.java.html

It could vary widely from one JDK to the next, so i definitely wouldn't rely on it.

That being said, if consistent iteration order is something you really need, you might want to try a LinkedHashMap.