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.
java code
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet())
{
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

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.

java code
Map<Integer, Integer> map = new HashMap<Integer, Integer>();

//iterating over keys only
for (Integer key : map.keySet())
{
System.out.println("Key = " + key);
}

//iterating over values only
for (Integer value : map.values())
{
System.out.println("Value = " + value);
}
[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:

java code
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext())
{
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

Without Generics:

java code
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext())
{
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}
  • 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).

java code
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer key : map.keySet())
{
Integer value = map.get(key);
System.out.println("Key = " + key + ", Value = " + value);
}
  • 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.
java code
for(Map.Entry<Integer, String> entry : map.entrySet())
{
System.out.printf("Key : %s and Value: %s %n", entry.getKey(), entry.getValue());
}
[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:

java code
Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry<Integer, String> entry = iterator.next();
System.out.printf("Key : %s and Value: %s %n", entry.getKey(), entry.getValue());
iterator.remove(); // right way to remove entries from Map,
// avoids ConcurrentModificationException
}

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.

java code
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Best way to iterate over Map in Java, including any implementation e.g.
* HashMap, TreeMap, LinkedHashMap, ConcurrentHashMap and Hashtable.
* Java 1.5 foreach loop is most elegant and combined with entry set also
* gives best performance, but not suitable for removing entries, as you don't have
* reference to internal Iterator.
* * Only way to remove entries from Map without throwing ConcurrentModificationException
* is to use Iterator and while loop. * */
public class WikitechyHashMapIteratorExample
{

public static void main(String args[]) {

// Initializing HashMap with some key values
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Core Java");
map.put(2, "Java SE");
map.put(3, "Java ME");
map.put(4, "Java EE");
map.put(5, "Java FX");

// Iterate over HashMap using foreach loop
System.out.println("Java 1.5 foreach loop provides most elegant
way to iterate over HashMap in Java");
for(Map.Entry<Integer, String> entry : map.entrySet()){
System.out.printf("Key : %s and Value: %s %n", entry.getKey(),
entry.getValue());
}
// Better way to loop over HashMap, if you want to remove entry
System.out.println("Use Iterator and while loop, if you want
to remove entries from HashMap during iteration");
Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
while(iterator.hasNext())
{
Map.Entry<Integer, String> entry = iterator.next();
System.out.printf("Key : %s and Value: %s %n", entry.getKey(),
entry.getValue());
iterator.remove(); // right way to remove entries from Map,
// avoids ConcurrentModificationException
}
}

}

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: