iterating over and removing from a map
As of Java 8 you could do this as follows:
map.entrySet().removeIf(e -> <boolean expression>);
Oracle Docs: entrySet()
The set is backed by the map, so changes to the map are reflected in the set, and vice-versa
How to remove a key from HashMap while iterating over it?
Try:
Iterator<Map.Entry<String,String>> iter = testMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String,String> entry = iter.next();
if("Sample".equalsIgnoreCase(entry.getValue())){
iter.remove();
}
}
With Java 1.8 and onwards you can do the above in just one line:
testMap.entrySet().removeIf(entry -> "Sample".equalsIgnoreCase(entry.getValue()));
Delete elements from Hashmap while iterating over it
To remove a element whilst in the middle of iterating, use Iterator.remove()
.
ES6: Is it dangerous to delete elements from Set/Map during Set/Map iteration?
Yes, you can simplify to that, it's totally safe.
- Sets and Maps are always iterated in insertion order
- Deleting an item does not affect the position of any iterator - you can visualise the shape of the collection not being changed, just being emptied.
- So: elements that are deleted and have not yet been iterated won't be iterated
- Elements that have already been iterated and are deleted (like in your case) won't affect anything but other iterations/lookups.
- Elements that are added (and are not already part of the collection) during the iteration will always be iterated
From that last point follows that the only dangerous thing to do would be something like
const s = new Set([1]);
for (let x of s) {
s.delete(x);
s.add(1);
}
but not because of undefined behaviour or memory accumulation, but because of the infinite loop.
How to remove from a map while iterating it?
The standard associative-container erase idiom:
for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
if (must_delete)
{
m.erase(it++); // or "it = m.erase(it)" since C++11
}
else
{
++it;
}
}
Note that we really want an ordinary for
loop here, since we are modifying the container itself. The range-based loop should be strictly reserved for situations where we only care about the elements. The syntax for the RBFL makes this clear by not even exposing the container inside the loop body.
Edit. Pre-C++11, you could not erase const-iterators. There you would have to say:
for (std::map<K,V>::iterator it = m.begin(); it != m.end(); ) { /* ... */ }
Erasing an element from a container is not at odds with constness of the element. By analogy, it has always been perfectly legitimate to delete p
where p
is a pointer-to-constant. Constness does not constrain lifetime; const values in C++ can still stop existing.
Iterating through a HashMap while removing AND updating the collection
Since Map#entrySet
returns a view of the mappings in the map, directly set the value of the Entry
to update it.
if (entry.getValue() == 1) {
iterator.remove();
} else {
entry.setValue(entry.getValue() - 1);
}
Related Topics
Only Using @JSONignore During Serialization, But Not Deserialization
Which Cipher Suites to Enable for Ssl Socket
How to Load Classes at Runtime from a Folder or Jar
What Are Classes, References, and Objects
Regex to Match Only Commas Not in Parentheses
Java.Lang.Unsatisfiedlinkerror No *****.Dll in Java.Library.Path
Getting Random Numbers in Java
Adding Files to Java Classpath at Runtime
How to Add a Filter Class in Spring Boot
A Simple Scenario Using Wait() and Notify() in Java
How to Save the State of My Program and Then Load It
Processbuilder: Forwarding Stdout and Stderr of Started Processes Without Blocking the Main Thread
Java Byte Array to String to Byte Array
Java Random Always Returns the Same Number When I Set the Seed