I am removing comment nodes with jsoup and found something I do not understand.
This code works:
Example 1:
private static void removeComments(Node node) {
for (int i = 0; i < node.childNodes().size();) {
Node child = node.childNode(i);
if (child.nodeName().equals("#comment"))
child.remove();
else {
removeComments(child);
i++;
}
}
But this code throws an ConcurrentModificationException:
Example 2
private static void removeComments(Node node) {
node.childNodes()
.forEach(n -> {
if (n.nodeName().equals("#comment")) {
n.remove();
} else {
removeComments(n);
}
});
}
I try to write short, easy to understand code, ternary operator not supporting two void returns already destroyed my "oneline" approach. What limitation did I hit with that strange behaviour?
ConcurrentModificationException
occurs when you modify the list (by adding or removing elements) while traversing a list with an Iterator.
You can't modify a List in a for/each loop, which is syntactic sugar around the Iterator as an implementation detail. You can only safely call .remove()
when using the Iterator directly.
Calling .remove()
inside the for/each loop modifies the contents, and the Iterator that is used behind the scenes sees this and throws this exception.
Read about How to Avoid ConcurrentModificationException when using an Iterator.