Java Map Interface

  • A map contains values on the basis of key i.e. key and value pair. Each key and value pair is known as an entry. Map contains only unique keys.
  • Map is useful if we have to search, update or delete elements on the basis of key.

Map.Entry Interface

  • Entry is the sub interface of Map.
  • So we will be accessed it by Map.Entry name.
  • It provides methods to get key and value.

How to Iterate Over a Map in Java

  • There are several ways of iterating over a Map in Java.
  • Since all maps in Java implement Map interface, following techniques will work for any map implementation (HashMap, TreeMap, LinkedHashMap, Hashtable, etc.)
    • Iterating over entries using For-Each loop.
    • Iterating over keys or values using For-Each loop.
    • Iterating using Iterator.
    • Iterating over keys and searching for values (inefficient).

Method 1: Iterating over entries using For-Each loop.

  • This is the most common method and is preferable in most cases.
  • It should be used if we need both map keys and values in the loop.
[pastacode lang=”java” manual=”Map%3CInteger%2C%20Integer%3E%20map%20%3D%20new%20HashMap%3CInteger%2C%20Integer%3E()%3B%0Afor%20(Map.Entry%3CInteger%2C%20Integer%3E%20entry%20%3A%20map.entrySet())%20%0A%7B%0A%20%20%20%20System.out.println(%22Key%20%3D%20%22%20%2B%20entry.getKey()%20%2B%20%22%2C%20Value%20%3D%20%22%20%2B%20entry.getValue())%3B%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

Note:

  • For-Each loop was introduced in Java 5, so this method is working only in newer versions of the language.
  • In addition For-Each loop will throw NullPointerException if we try to iterate over a map that is null, so before iterating we should always check for null references.

Method 2: Iterating over keys or values using For-Each loop.

[pastacode lang=”java” manual=”Map%3CInteger%2C%20Integer%3E%20map%20%3D%20new%20HashMap%3CInteger%2C%20Integer%3E()%3B%0A%0A%2F%2Fiterating%20over%20keys%20only%0Afor%20(Integer%20key%20%3A%20map.keySet())%20%0A%7B%0A%20%20%20%20System.out.println(%22Key%20%3D%20%22%20%2B%20key)%3B%0A%7D%0A%0A%2F%2Fiterating%20over%20values%20only%0Afor%20(Integer%20value%20%3A%20map.values())%20%0A%7B%0A%20%20%20%20System.out.println(%22Value%20%3D%20%22%20%2B%20value)%3B%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/] [ad type=”banner”]
  • If we need only keys or values from the map, we can iterate over keySet or values instead of entrySet.
  • This method gives a slight performance advantage over entrySet iteration (about 10% faster).

Method 3: Iterating using Iterator.

Using Generics:

[pastacode lang=”java” manual=”Map%3CInteger%2C%20Integer%3E%20map%20%3D%20new%20HashMap%3CInteger%2C%20Integer%3E()%3B%0AIterator%3CMap.Entry%3CInteger%2C%20Integer%3E%3E%20entries%20%3D%20map.entrySet().iterator()%3B%0Awhile%20(entries.hasNext())%20%0A%7B%0A%20%20%20%20Map.Entry%3CInteger%2C%20Integer%3E%20entry%20%3D%20entries.next()%3B%0A%20%20%20%20System.out.println(%22Key%20%3D%20%22%20%2B%20entry.getKey()%20%2B%20%22%2C%20Value%20%3D%20%22%20%2B%20entry.getValue())%3B%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

Without Generics:

[pastacode lang=”java” manual=”Map%20map%20%3D%20new%20HashMap()%3B%0AIterator%20entries%20%3D%20map.entrySet().iterator()%3B%0Awhile%20(entries.hasNext())%20%0A%7B%0A%20%20%20%20Map.Entry%20entry%20%3D%20(Map.Entry)%20entries.next()%3B%0A%20%20%20%20Integer%20key%20%3D%20(Integer)entry.getKey()%3B%0A%20%20%20%20Integer%20value%20%3D%20(Integer)entry.getValue()%3B%0A%20%20%20%20System.out.println(%22Key%20%3D%20%22%20%2B%20key%20%2B%20%22%2C%20Value%20%3D%20%22%20%2B%20value)%3B%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]
  • Initially, it is the only way to iterate over a map in older versions of Java.
  • The other important feature is that it is the only method that allows to remove entries from the map during iteration by calling iterator.remove().
  • If we try to do this during For-Each iteration we will get “unpredictable results” according to Javadoc.
  • From a performance point of view this method is equal to a For-Each iteration.

Method 4: Iterating over keys and searching for values (inefficient).

[pastacode lang=”java” manual=”Map%3CInteger%2C%20Integer%3E%20map%20%3D%20new%20HashMap%3CInteger%2C%20Integer%3E()%3B%0Afor%20(Integer%20key%20%3A%20map.keySet())%20%0A%7B%0A%20%20%20%20Integer%20value%20%3D%20map.get(key)%3B%0A%20%20%20%20System.out.println(%22Key%20%3D%20%22%20%2B%20key%20%2B%20%22%2C%20Value%20%3D%20%22%20%2B%20value)%3B%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]
  • This might look like a cleaner alternative for method 1, but in practice it is slow and inefficient as getting values by a key might be time-consuming.
  •  If we have FindBugs installed, it will detect this and warn about inefficient iteration.

Best way to Iterate over HashMap in Java

  • Here is the code example of Iterating over any Map class in Java (e.g. Hashtable or LinkedHashMap)
  • we used HashMap for iteration purpose, we can apply same technique to other Map implementations.
  • Since we are only using methods from java.uti.Map interface, solution is extensible to all kinds of Map in Java.
  • We will use Java 1.5 foreach loop and Iterating over each Map.Entry object, which we get by calling Map.entrySet() method.
  • Using Generics to avoid type casting.
[pastacode lang=”java” manual=”for(Map.Entry%3CInteger%2C%20String%3E%20entry%20%3A%20map.entrySet())%0A%7B%20%0ASystem.out.printf(%22Key%20%3A%20%25s%20and%20Value%3A%20%25s%20%25n%22%2C%20entry.getKey()%2C%20entry.getValue())%3B%20%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/] [ad type=”banner”]
  • This above code has one drawback, we can not remove entries without risking ConcurrentModificationException.

Removing Entries from Map in Java:

  • One reason for iterating over Map is removing selected key value pairs from Map.
  • This is a general Map requirement and holds true for any kind of Map e.g. HashMap, Hashtable, LinkedHashMap or even relatively new ConcurrentHashMap.
  • When we use foreach loop, it internally translated into Iterator code, but without explicit handle to Iterator, we just can not remove entries during Iteration. If you do,  your Iterator may throw ConcurrentModificationException.
  • To avoid this, we need to use explicit Iterator and while loop for traversal. We will still use entrySet() for performance reason, but we will use Iterator’s remove() method for deleting entries from Map.

Here code example  to remove key values from HashMap in Java:

[pastacode lang=”java” manual=”Iterator%3CMap.Entry%3CInteger%2C%20String%3E%3E%20iterator%20%3D%20map.entrySet().iterator()%3B%0Awhile(iterator.hasNext())%0A%7B%0A%20%20%20Map.Entry%3CInteger%2C%20String%3E%20entry%20%3D%20iterator.next()%3B%0A%20%20%20System.out.printf(%22Key%20%3A%20%25s%20and%20Value%3A%20%25s%20%25n%22%2C%20entry.getKey()%2C%20entry.getValue())%3B%0A%20%20%20iterator.remove()%3B%20%2F%2F%20right%20way%20to%20remove%20entries%20from%20Map%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20avoids%20ConcurrentModificationException%0A%7D%0A” message=”java code” highlight=”” provider=”manual”/]

we are using remove() method from Iterator and not from java.util.Map, which accepts a key object. This code is safe from ConcurrentModificationException.

Removing Entries from Map in Java:

  • One reason for iterating over Map is removing selected key value pairs from Map.
  • This is a general Map requirement and holds true for any kind of Map (e.g. HashMap, Hashtable, LinkedHashMap or even relatively new ConcurrentHashMap)
  • When we use foreach loop, it internally translated into Iterator code, but without explicit handle to Iterator, we just can not remove entries during Iteration. If we do,  our Iterator may throw ConcurrentModificationException.
  • To avoid this, we need to use explicit Iterator and while loop for traversal. We will still use entrySet() for performance reason, but we will use Iterator’s remove() method for deleting entries from Map.

HashMap Iterator Example

Here is complete code example, combining both approaches for iterating over HashMap in Java.

[pastacode lang=”java” manual=”import%20java.util.HashMap%3B%0Aimport%20java.util.Iterator%3B%20%0Aimport%20java.util.Map%3B%0A%20%2F**%0A%20*%20Best%20way%20to%20iterate%20over%20Map%20in%20Java%2C%20including%20any%20implementation%20e.g.%20%0A*%20HashMap%2C%20TreeMap%2C%20LinkedHashMap%2C%20ConcurrentHashMap%20and%20Hashtable.%0A%20*%20Java%201.5%20foreach%20loop%20is%20most%20elegant%20and%20combined%20with%20entry%20set%20also%0A%20*%20gives%20best%20performance%2C%20but%20not%20suitable%20for%20removing%20entries%2C%20as%20you%20don’t%20have%0A%20*%20reference%20to%20internal%20Iterator.%20%0A*%20*%20Only%20way%20to%20remove%20entries%20from%20Map%20without%20throwing%20ConcurrentModificationException%0A%20*%20is%20to%20use%20Iterator%20and%20while%20loop.%20*%20*%2F%0Apublic%20class%20WikitechyHashMapIteratorExample%20%0A%7B%0A%0A%20%20%20%20public%20static%20void%20main(String%20args%5B%5D)%20%7B%0A%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20Initializing%20HashMap%20with%20some%20key%20values%0A%20%20%20%20%20%20%20%20Map%3CInteger%2C%20String%3E%20map%20%3D%20new%20HashMap%3CInteger%2C%20String%3E()%3B%0A%20%20%20%20%20%20%20%20map.put(1%2C%20%22Core%20Java%22)%3B%0A%20%20%20%20%20%20%20%20map.put(2%2C%20%22Java%20SE%22)%3B%0A%20%20%20%20%20%20%20%20map.put(3%2C%20%22Java%20ME%22)%3B%0A%20%20%20%20%20%20%20%20map.put(4%2C%20%22Java%20EE%22)%3B%0A%20%20%20%20%20%20%20%20map.put(5%2C%20%22Java%20FX%22)%3B%0A%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20Iterate%20over%20HashMap%20using%20foreach%20loop%0A%20%20%20%20%20%20%20%20System.out.println(%22Java%201.5%20foreach%20loop%20provides%20most%20elegant%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20way%20to%20iterate%20over%20HashMap%20in%20Java%22)%3B%0A%20%20%20%20%20%20%20%20for(Map.Entry%3CInteger%2C%20String%3E%20entry%20%3A%20map.entrySet())%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.printf(%22Key%20%3A%20%25s%20and%20Value%3A%20%25s%20%25n%22%2C%20entry.getKey()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entry.getValue())%3B%0A%20%20%20%20%20%20%20%20%7D%0A%2F%2F%20Better%20way%20to%20loop%20over%20HashMap%2C%20if%20you%20want%20to%20remove%20entry%0A%20%20%20%20%20%20%20%20System.out.println(%22Use%20Iterator%20and%20while%20loop%2C%20if%20you%20want%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20to%20remove%20entries%20from%20HashMap%20during%20iteration%22)%3B%0A%20%20%20%20%20%20%20%20Iterator%3CMap.Entry%3CInteger%2C%20String%3E%3E%20iterator%20%3D%20map.entrySet().iterator()%3B%0A%20%20%20%20%20%20%20%20while(iterator.hasNext())%0A%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20Map.Entry%3CInteger%2C%20String%3E%20entry%20%3D%20iterator.next()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.printf(%22Key%20%3A%20%25s%20and%20Value%3A%20%25s%20%25n%22%2C%20entry.getKey()%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20entry.getValue())%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20iterator.remove()%3B%20%2F%2F%20right%20way%20to%20remove%20entries%20from%20Map%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20avoids%20ConcurrentModificationException%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20%20%20%20%0A%20%20%0A%7D%0A%0A” message=”java code” highlight=”” provider=”manual”/]

Output:

Java 1.5 foreach loop provides most elegant way to iterate over HashMap in Java

Key : 1 and Value: Core Java

Key : 2 and Value: Java SE

Key : 3 and Value: Java ME

Key : 4 and Value: Java EE

Key : 5 and Value: Java FX

Use Iterator and while loop, if you want to remove entries from HashMap during iteration

Key : 1 and Value: Core Java

Key : 2 and Value: Java SE

Key : 3 and Value: Java ME

Key : 4 and Value: Java EE

Key : 5 and Value: Java FX

[ad type=”banner”]

Categorized in: