If I have an object implementing the Map interface in Java and I wish to iterate over every pair contained within it, what is the most efficient way of going through the map? Will the ordering of elements depend on the specific map implementation that I have for the interface?
Yes, the order depends on the specific Map implementation.
@ScArcher2 has the more elegant Java 1.5 syntax. In 1.4, I would do something like this:
Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
// ...
}
for (Map.Entry<String, String> entry : map.entrySet())
{
System.out.println(entry.getKey() + "/" + entry.getValue());
}
In theory, the most efficient way will depend on which implementation of Map. The official way to do this is to call map.entrySet(), which returns a set of Map.Entry, each of which contains a key and a value (entry.getKey() and entry.getValue()).
In an idiosyncratic implementation, it might make some difference whether you use map.keySet(), map.entrySet() or something else. But I can't think of a reason why anyone would write it like that. Most likely it makes no difference to performance what you do.
And yes, the order will depend on the implementation - as well as (possibly) the order of insertion and other hard-to-control factors.
[edit] I wrote valueSet() originally but of course entrySet() is actually the answer.
Typical code for iterating over a map is:
Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
String key = entry.getKey();
Thing thing = entry.getValue();
...
}
HashMap is the canonical map implementation and doesn't make guarantees (or though it should not change order if no mutating operation are performed on it). SorterMap will return entries on however the map sorts the keys. LinkedHashMap will either return entries in insertion-order or access-order depending upon how it has been constructed. EnumMap returns entries in natural order of keys.
Note, IdentityHashMap entrySet iterator currently has a peculiar implementation which returns the same Map.Entry instance for every item in the entrySet! However, every time a new the iterator advances the Map.Entry is updated.
This is a two part question:
How to iterate over the entries of a Map - @ScArcher2 has asnwered that perfectly.
What is the order of iteration - if you are just using Map
, then strictly speaking, there are no ordering guarantees. So you shouldn't really rely on the ordering given by any implementation. However, the SortedMap
interface extends Map
and provides exactly what you are looking for - implementations will aways give a consistent sort order.
NavigableMap
is another useful extension - this is a SortedMap
with additional methods for finding entries by their ordered position in the key set. So potentially this can remove the need for iterating in the first place - you might be able to find the specific entry you are after using the higherEntry
, lowerEntry
, celingEntry
or floorEntry
methods. The descendingMap
method even gives you an `explicit method of reversing the traversal order.
FYI, you can also use map.keySet()
and map.values()
if you're only interested in keys/values of the map and not the other.
I typically do it by iterating over the keyset instead of the entry set. I find the code looks a bit cleaner. You also know that you are always looking at items in keys order for ordered maps such as the LinkedHashMap:
for (String key: map.keySet()) {
System.out.println(key + "/" + map.get(key));
}
Example of using iterator and generics:
Iterator<Map.Entry<String, String>> entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
String key = entry.getKey();
String value = entry.getValue();
// ...
}
try this with java 1.4
for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){
Entry entry = (Entry) entries.next();
System.out.println(entry.getKey() + "/" + entry.getValue());
//...
}