Home > Software engineering >  Java - Recursion to get children from objects only works with extra list
Java - Recursion to get children from objects only works with extra list

Time:08-12

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:

  1. Don't remove during iteration. That is exactly what you've done.

  2. Use a Iterator directly, this will prevent getting an Exception.

  3. Make use of "removeIf()". You can remove objects from a list, using functional programming (Lambda) inside the method call.

  4. 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.

  • Related