Remove multiple keys from Map in efficient way?

JavaDictionary

Java Problem Overview


I have a Map<String,String> with large number of key values pairs. Now I want to remove selected keys from that Map. Following code shows what I did to achieve that.

Set keySet = new HashSet(); //I added keys to keySet which I want to remove. 

Then :

Iterator entriesIterator = keySet.iterator();
while (entriesIterator.hasNext()) {
   map.remove( entriesIterator.next().toString());
} 

This is working fine. What would be the better approach?

Java Solutions


Solution 1 - Java

Assuming your set contains the strings you want to remove, you can use the keySet method and map.keySet().removeAll(keySet);.

> keySet returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

Contrived example:

Map<String, String> map = new HashMap<>();
map.put("a", "");
map.put("b", "");
map.put("c", "");

Set<String> set = new HashSet<> ();
set.add("a");
set.add("b");

map.keySet().removeAll(set);

System.out.println(map); //only contains "c"

Solution 2 - Java

For the sake of completion, and since Google brings you here when you look for a way to achieve this:

map.entrySet().removeIf(entry -> /* decide what you want to remove here */ );

This does not assume you have a predefined set of keys to remove but rather assumes you have a condition on which the keys should be removed. From the question, it is unclear if these keys are added manually or based on some sort of condition. In the latter case, this might be the cleaner code.

For the former case, this (untested) code might work as well:

map.entrySet().removeIf(entry -> keySet.contains(entry.getKey()) );

But obviously the answer provided by @assylias is much cleaner in this case!

Solution 3 - Java

Just for the sake of completeness:

As guessed java.util.AbstractSet#removeAll really iterates over all entries, but with one little trick: It uses the iterator of the smaller collection:

if (size() <= collection.size()) {
	Iterator<?> it = iterator();
	while (it.hasNext()) {
		if (collection.contains(it.next())) {
			it.remove();
		}
	}
} else {
	Iterator<?> it = collection.iterator();
	while (it.hasNext()) {
		remove(it.next());
	}
}

Solution 4 - Java

Using Java stream:

keySet.forEach(map::remove);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRuchira Gayan RanaweeraView Question on Stackoverflow
Solution 1 - JavaassyliasView Answer on Stackoverflow
Solution 2 - JavaMaverick283View Answer on Stackoverflow
Solution 3 - JavaSebastianView Answer on Stackoverflow
Solution 4 - JavaAbdullView Answer on Stackoverflow