Hello guys, Can you remove a key while iterating over HashMap in Java? This is one of the interesting interview questions as well as a common problem Java developers face while writing code using HashMap. Some programmers will say No, you cannot remove elements from HashMap while iterating over it. This will fail fast and throw concurrent modification exceptions. They are right but not completely. It's true that the iterator of HashMap is a fail-fast iterator but you can still remove elements from HashMap while iterating by using Iterator's remove() method.
This is the same technique that we have used in past to remove elements while iterating over a List in Java. The key here is not to use the remove() method from Map or List interface to avoid java.util.ConcurrentModfiicationException in Java.
The ConcurrentModificationException comes when you use Map.remove(Object key) to remove a key. Remember, when you remove a key, the mapping itself is removed i.e. both key and value objects are removed from Map and its size reduced by 1.
Here are the exact steps to remove elements from HashMap while Iterating
1. Get sets of keys by calling the Map.keySet() method
2. Get the Iterator from this set by calling the iterator() method of the Set interface.
3. Iterate over Map using this Iterator and while loop
4. Remove an entry from a map based on matching key from set like you can compare the key from Set with the item you want to remove by using Iterator.remove() method
How to remove a key from HashMap in Java? Example
Here is an example to remove keys from HashMap while iterating. In this example, I have a Map of various Java and Spring certifications and their cost like OCAJP (1Z0-808) cost around 248 US Dollars, same is for OCPJP 8 (1Z0-809), while Spring certifications provided by Pivotal like Spring Professional Certification Exam and Spring Web Application Developer Exam cost around 200 USD each (see here).While Iterating over Map, I compare the key with the OCMJEA (Oracle Certified Master Java Enterprise Architect), and if the key matches then I remove it from the Map.
Here, I have used the remove() method of HashMap, hence this program will throw ConcurrentModfiicationException.
You can see the Iterator of HashMap throws java.util.ConcurrentModificationException as soon as you try to remove an entry while iterating over Map because the iterator is fail-fast. If this had been a ConcurentHashMap then it won't throw the ConcurrentModficationExcetpion. Now, let's see the correct way to remove an entry from HashMap while iterating over it.
import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Java Program to remove mapping from HashMap while Iterating * using Map.remove(Object key) method */ public class Main { public static void main(String args[]) { Map<String, Integer> certificationCost = new HashMap<>(); certificationCost.put("OCAJP 1Z0-808", 248); certificationCost.put("OCPJP 1Z0-809", 248); certificationCost.put("Spring Professional Certification Exam", 200); certificationCost.put("Spring Web Application Developer Exam", 200); certificationCost.put("OCMJEA 1Z0-807", 600); // let's try to remove element from Hashmap // using Map.remove(Object key) method // this will not work, will throw ConcurrentModfiicationException Set<String> setOfCertifications = certificationCost.keySet(); for(String certificaiton : setOfCertifications){ if(certificaiton.contains("OCMJEA")){ certificationCost.remove(certificaiton); } } } } Output Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) at java.util.HashMap$KeyIterator.next(HashMap.java:1453) at Main.main(Main.java:24)
You can see the Iterator of HashMap throws java.util.ConcurrentModificationException as soon as you try to remove an entry while iterating over Map because the iterator is fail-fast. If this had been a ConcurentHashMap then it won't throw the ConcurrentModficationExcetpion. Now, let's see the correct way to remove an entry from HashMap while iterating over it.
The right way to Remove a key from HashMap while Iterating in Java
Here is the right way to remove a key or an entry from HashMap in Java while iterating over it. This code uses Iterator and its remove() method to delete a key from HashMap. When you remove a key, the value also gets removed from HashMap i.e. it's a shortcut to remove an entry from HashMap in Java.import java.util.HashMap; import java.util.Iterator; import java.util.Map; /* * Java Program to remove mapping from HashMap while Iterating * using Iterator's remove() method */ public class Main { public static void main(String args[]) { Map<String, Integer> certificationCost = new HashMap<>(); certificationCost.put("OCAJP 1Z0-808", 248); certificationCost.put("OCPJP 1Z0-809", 248); certificationCost.put("Spring Professional Certification Exam", 200); certificationCost.put("Spring Web Application Developer Exam", 200); certificationCost.put("OCMJEA 1Z0-807", 600); // Map - before removing a mapping System.out.println("before: " + certificationCost); // let's use Iterator to remove a key from HashMap while iterating Iterator<String> iterator = certificationCost.keySet().iterator(); while(iterator.hasNext()){ String certification = iterator.next(); if(certification.contains("OCMJEA")){ iterator.remove(); } } // Map - after removing a mapping System.out.println("after: " + certificationCost); } } Output before: {Spring Professional Certification Exam=200, OCMJEA 1Z0-807=600, Spring Web Application Developer Exam=200, OCPJP 1Z0-809=248, OCAJP 1Z0-808=248} after: {Spring Professional Certification Exam=200, Spring Web Application Developer Exam=200, OCPJP 1Z0-809=248, OCAJP 1Z0-808=248}
From the output you can see that the entry associated with the "OCMJEA 1Z0-807" key is removed from the Map, there were 4 entries before removal and now there are only three entries remaining. Also, there is no ConcurrentModificationException occurs.
Java 8 Facts
In Java 8 you can use the map.values().removeAll(Collections.singleton(240)); to remove all key/value pairs where value is 240. See these Java 8 tutorials and courses to learn more about new methods added into existing interfaces in JDK 8.
That's all about how to remove a key or an entry/mapping while iterating over HashMap in Java. You cannot remove an entry while looping over Map but you can remove a key or value while iterating over it. Since Iterator of HashMap is fail-fast it will throw ConcurrentModificationException if you try to remove entry using Map.remove(Object key) method, the right way to remove an entry from the HashMap by using Iterator's remove() method.
Other Java Collection Articles You May like
- 25 Java Collection Interview Questions
- How HashMap works in Java
- How ConcurrentHashMap works in Java
- 20 ArrayList Interview Questions with Answers
- 100+ Data Structure and Algorithms Questions with Answers
- 75 Programming Interview Questions with Answers
- 15 Recursion Exercises for Java Programmers
- 5 Free Spring MVC Courses for Beginners
- 5 free SQL and Database Courses for Programmers
- 40 Java HashMap Interview Questions with answers
- How to sort HashMap by keys and values in Java 8
Thanks for reading this article this far. If you like this Java Collection tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a comment.
P. S. - If you want to learn HashMap and other Java collections in depth and looking for resources, you can also checkout this list of best Java Collections and Stream courses where I have shared engaging online courses to learn Java Collections framework in depth.
Hello Javin,
ReplyDeleteNice article, thanks.
In Java 8, there is yet another way to remove a key which is very succinct and elegant:
certificationCost.keySet().removeIf(certification -> certification.contains("OCMJEA"));
Cheers
Good callout for the convenience function. It has the same implementation as the article.
Delete