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.
No comments:
Post a Comment
Please do not add any spam links in the comments section.