1. Overview
In this tutorial, We'll learn
How to Iterate Map and How to Iteration
HashMap in Java using various ways.
Iterating is very common process in any programming language using very basic
for loop.
There are
6 different ways to extract or loop over Map in java such as using enhanced for loop, Iterator using
EntrySet, Java 8 and stream API.
Most exciting is about
lambda part and most of the projects are already migrated to Java 8 but may not be using full features of Java 8.
As all of us know,
ArrayList is directly iterated using Iterator but it is not possible encase of Map because Map is not under
Collection interface.
We must know about internals of
how hashmap works in java.
HashMap creates internally
Hashset and added
Entry objects into
Hashset.
Map.Entry object looks like below.
static class Node implements Map.Entry {
final int hash;
final K key;
V value;
Node next;
// constructor, setters and getters
}
In all examples today will be executed on the below input. All these values are stored in set in the form of
Node<String, String> which is an
Map.Entry object.
Map hashMap = new HashMap<>();
hashMap.put("Map", "HashMap");
hashMap.put("Set", "Hashset");
hashMap.put("List", "ArrayList");
2. Map.entrySet() using for each
Map has a method
entryset() which returns the Set object. In our case, it is
Set<Entry<String, String>> and this holds
Entry<String, String> objects.
Now we will
iterate through enhanced for loop this set. See the code below.
for (Map.Entry entry : hashMap.entrySet())
System.out.println("Key(Interface) = " + entry.getKey() + ", Value(Implementation class) = " + entry.getValue());
}
First, retrieving the each object from set in the form of entry object and then next calling
getKey() to get the key from
Node/Entry object and
getValue() method to get the value of the corresponding key.
Output:
Key(Interface) = Set, Value(Implementation class) = Hashset
Key(Interface) = List, Value(Implementation class) = ArrayList
Key(Interface) = Map, Value(Implementation class) = HashMap
This methodology is commonly used by all programmers if want to retrieve both key and value at the same time.
3. keySet() and values() methods
We
might need to get the only keys some scenario where values are not
required and vice versa. In these type of situations, we'll
try to minimize getting entire key-value pair. Map has provided methods to get only keys or values by invoking methods
keyset() and
values().
// Retrieving only keys
for (String interfaceName : hashMap.keySet()) {
System.out.println("Key(Interface): " + interfaceName);
}
// Retrieving only values
for (String ImplementationClassName : hashMap.values()) {
System.out.println("Value(Implementation class): " + ImplementationClassName);
}
Output:
Key(Interface): Set
Key(Interface): List
Key(Interface): Map
Value(Implementation class): Hashset
Value(Implementation class): ArrayList
Value(Implementation class): HashMap
4. entrySet().iterator()
Next approach is as Similar to Section 2, Here as well first need to
call the entrySet() method which returns set.
Now we have set object and
set has a method iterate().
See the below code.
Set> entrySet = hashMap.entrySet();
Iterator> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Entry entry = iterator.next();
System.out.println(
"Key(Interface) = " + entry.getKey() + ", Value(Implementation class) = " + entry.getValue());
}
We'll now iterate tradition mechanism using
hasNext() and
next() methods.
hasNext(): returns true if next element is present in the collection. Otherwise false.
next(): returns next object from collection.
Output will same as in section 2.
5. Lamda Expression - forEach()
Java 8 introduced Lamda concept which is in funcitonal programming.
Lamda's reduces code to very minimal to our core logic and remaing take care by Lamda.
Now take a look at the below code using
Map.forEach() method.
forEach method takes BiConsumer as argument and calls it's accept() method.
hashMap.forEach((k, v) -> System.out.println("Key(Interface) = " + k + ", Value(Implementation class) = " + v));
All of this logic now bacame to single line. This is the power of lambda.
(k, v) is passed to the
accept() method and adds
System.out.println() inside method body as below.
accept(String k, String v){
System.out.println("Key(Interface) = " + k + ", Value(Implementation class) = " + v)
}
Output will be same as section 2.
Look at interesting article on "
Iterating String Array Examples"
6. Stream API
Stream api also introduced in Java 8 and most powerful rich feature.
Stream api primarly designed for collection api and provides the way to process collection sequentially and parellel.
Iterating map using Stream api is simple. But streams are extremly useful when we do aggregation operations.
First invoke
entrySet().stream() method which inturn returns Stream object.
Stream> entriesStream = hashMap.entrySet().stream();
Next, Stream intreface has
void forEach(Consumer<? super T> action) method. This forEach method iterates the
Entry objects that are in the
entrySet(). See the below code.
entriesStream.forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));
Output:
Set - Hashset
List - ArrayList
Map - HashMap
We can still further
rewrite the above code into single line as below which will produce the same output.
hashMap.entrySet().stream().forEach(entry -> System.out.println(entry.getKey() + " - " + entry.getValue()));
7. Get Key and Search for it's value
As of now, we get both key and value at the same time in all above methods discussed as of now. But there is a
way to get keys first and iterate keys to get value for each key by calling map.get(key) method.
for (String key : hashMap.keySet()) {
String value = hashMap.get(key);
System.out.println(key + " - " + value);
}
This code works fine and generate the expected output but
this code is not efficient to run through huge key-value pair maps.
This solutin is not suggested and caught error complaining stating
"WMI_WRONG_MAP_ITERATOR" in
FingBugs because doing loop up for each key in map again calling get() method.
Use any one of above methods that will solve this problem.
8. Conclusion
In this tutoril, We've seen all possible ways on
how to iterate through a map in java including java 8 stream concpets.
Further more covered
Stream api forEach and map forEach methods with examples and
inefficient way of iterating map which is not suggested by FindBugs.
All codes shown in this tutorail are available on
GitHub.