Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is iteration order over the different Collection views of a given Map guaranteed to be consistent?

For a given type of Map, are there any guarantees that iterating over the Collection views returned by the keySet, values and entries methods are iterated in the same order?

Background: I'm wondering whether transforming

public static void doSomethingForEachEntry(Map<String, Integer> someMap) {

    for (String key : someMap.keySet()) {
        doSomething(someMap.get(key));
    }       
}

to

public static void doSomethingForEachEntry(Map<String, Integer> someMap) {

    for (Integer value : someMap.values()) {
        doSomething(value);
    }       
}

is guaranteed to keep iteration order unchanged.

like image 706
Hulk Avatar asked Jan 25 '16 10:01

Hulk


People also ask

Does HashMap iterate in order?

The HashMap in Java provides good performance but doesn't maintain any order of its elements. If you want insertion-order iteration with near-HashMap performance, you can use LinkedHashMap . If you want sorted-order iteration, you can use the TreeMap implementation of the Map interface.

Are HashMap Keys ordered?

As we know that Hash map in Java does not maintain insertion order either by key or by order. Also it does not maintain any other order while adding entries to it.

Are Java maps ordered?

The map is ordered according to the natural ordering of its keys, or by a Comparator typically provided at sorted map creation time. This order is reflected when iterating over the sorted map's collection views (returned by the entrySet , keySet and values methods).

Is keySet ordered Java?

A map's keySet function returns a Set and the set's iterator method says this in its documentation: "Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee)."


1 Answers

While it is true that you can't rely on a specific ordering unless the Map implementation explicitly defines it, there is a sentence in the API documentation that implies there is a single shared ordering for the map and all its collection views:

The order of a map is defined as the order in which the iterators on the map's collection views return their elements.

(my emphasis)

For this to be satisfied, a map has an inherent order (even though it may not be specified, and may change as the map is modified), and all collection views must correspond to this order. Whether that constitutes a guarantee, and in particular whether all third-party map implementations will honour it, is another question.

It's also worth noting that these are explicitly defined in the Map interface as views that are backed by the map, (e.g. if you remove an element from the keySet, the corresponding Map entry must be removed from the map). This means in reality it's less likely that you'll get different orderings from a correct Map implementation than it would be if for example you made shallow copies of the collection views.

Having said all that, if the question is "is this a safe refactor?" then the answer is "yes, as long as the original code isn't itself broken". If the method relies on a specific ordering, and therefore a specific Map implementation, the method should be declared to accept only that type of Map. Otherwise, you have a potential timebomb if the underlying Map implementation changes down the line (and I have seen software break in real life because of this with a JDK update).

If a particular caller is relying on a specific ordering because it knows it's passing an ordered Map implementation, that's fine and that order will be preserved after your refactor.

like image 75
CupawnTae Avatar answered Dec 23 '22 21:12

CupawnTae