I'm using a recursive method to get all children from an object.
Class for the object:
class Mandant {
private String id;
private String parentId;
public Mandant(String id, String parentId) {
this.id = id;
this.parentId = parentId;
}
plus getter and setter.
The method:
private static List<Mandant> getAllChildren(Mandant mandant, List<Mandant> allMandants) {
List<Mandant> result = new ArrayList<>();
for (Mandant man: allMandants)
if (man.getParentId() != null && man.getParentId().equals(mandant.getId())) {
result.add(man);
}
for (Mandant man: result) {
result.addAll(getAllChildren(man, allMandants));
}
return result;
}
This throws an exception:
Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
But if I'm using an extra list for storing the recursive call it works:
private static List<Mandant> getAllChildren(Mandant mandant, List<Mandant> allMandants) {
List<Mandant> result = new ArrayList<>();
for (Mandant man: allMandants)
if (man.getParentId() != null && man.getParentId().equals(mandant.getId())) {
result.add(man);
}
List<Mandant> lowerChildren = new ArrayList<>();
for (Mandant man: result) {
lowerChildren.addAll(getAllChildren(man, allMandants));
}
result.addAll(lowerChildren);
return result;
}
Does anyone know why?
CodePudding user response:
The ConcurrentModificationException is an Exception, thrown when you try to modify a list while iterating through it. You should not iterate over a list an remove objects during this process.
I will explain several ways to avoid this exception:
Don't remove during iteration. That is exactly what you've done.
Use a Iterator directly, this will prevent getting an Exception.
Make use of "removeIf()". You can remove objects from a list, using functional programming (Lambda) inside the method call.
You can filter the List, using Streams. This is more advanced and actually not really necessary. But you will not face a ConcurrentModificationException doing this.
From all these ways, I use Iterators the most, but I think you should try and test. Every way has its own usecase.