Recursive method with ArrayList in java

Hi, I'm in the middle of a problem with a task exercise.

I have a class like this:

UML of Class

UML OF THE CLASS

And I have to put together a recursive public method, which returns an ArrayList with the total number of sub-sectors (considering that each sub-sector can in turn have sub-sectors)

The class (in addition to the get and set methods that do not paste them so as not to fill as much of code)

public class Sector {

private int numero;
private String denominacion;
private String tipo;

private ArrayList<Sector> sectores = new ArrayList<>();   

public Sector(int numero, String denominacion, String tipo) {
    this.numero = numero;
    this.denominacion = denominacion;
    this.tipo = tipo;
}

This is the code of the method

public ArrayList<Sector> obtenerTotalSubsectores(Sector sector, ArrayList<Sector> sectores) {
    sectores.add(this);
        if (sector.getSectores() != null) {
            for(Sector sector1 : sector.getSectores()) {
                obtenerTotalSubsectores(sector1, sectores);
            }
        }        
    return sectores;
}

And the main code

    Sector s1 = new Sector(100, "sales", "sales");
    Sector s1_1 = new Sector (101, "minor sales", "minor");
    Sector s1_2 = new Sector (102, "mayor sales", "mayor");
    Sector s1_2_1 = new Sector (102, "lala sales", "lalala");

    s1.getSectores().add(s1_1);
    s1.getSectores().add(s1_2);
    s1_2.getSectores().add(s1_2_1);

    Sector s2 = new Sector(200, "Sistemas", "sistemas");        
    Sector s2_1 = new Sector(200, "Soporte Técnico", "soporte");

    s2.getSectores().add(s2_1);
    s1.getSectores().add(s2);   

    s1.obtenerTotalSubsectores(s1, s1.getSectores());

And the error that pulls me

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at ejercicio_c_actividad.Sector.obtenerTotalSubsectores(Sector.java:79)
at ejercicio_c_actividad.Main.main(Main.java:61)
C:\xxx\xxx\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

Any idea what I'm doing wrong?

 5
Author: Tom, 2016-08-18

1 answers

SOLUTION TO YOUR CODE

You have two failures, first of all, although it would be the right thing, you can not add this to each recursion, because the method executes one Sector and you pass it another!!!! So you will add the same to each turn, ignoring the sector to be processed itself. So:

public ArrayList<Sector> obtenerTotalSubsectores(Sector sector, ArrayList<Sector> sectores) {
    sectores.add(sector);
    if (sector.getSectores() != null) {
        for (Sector sector1 : sector.getSectores()) {
            obtenerTotalSubsectores(sector1, sectores);
        }
    }
    return sectores;
}

The second is that you send a full ArrayList of sectors, which does not have much logic, you must create a new object to fill, modifying your main:

ArrayList<Sector> sectores = new ArrayList<Sector>();
s1.obtenerTotalSubsectores(s1, sectores);


System.out.println("TOTAL SECTORES EN EL " + s1.getNumero());
for (Sector s : sectores) {
    System.out.println(s.toString());
}

sectores.clear();
s2.obtenerTotalSubsectores(s2, sectores);

System.out.println("\n\nTOTAL SECTORES EN EL " + s2.getNumero());
for (Sector s : sectores) {
    System.out.println(s.toString());
}

We have this output (he added a toString() standard to check the outputs more easily)

TOTAL SECTORES EN EL 100
Sector [numero=100, denominacion=sales, tipo=sales, sectores=[Sector [numero=101, denominacion=minor sales, tipo=minor, sectores=[]], Sector [numero=102, denominacion=mayor sales, tipo=mayor, sectores=[Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]]], Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]]]
Sector [numero=101, denominacion=minor sales, tipo=minor, sectores=[]]
Sector [numero=102, denominacion=mayor sales, tipo=mayor, sectores=[Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]]]
Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]
Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]
Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]


TOTAL SECTORES EN EL 200
Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]
Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]

CORRECT SOLUTION

Now, clarified that you are failing, I think you are not using the recursion correctly, I explain, since the method has the Sector, you do not have to pass it to the method each time, since it will be executed within it, you just need to pass the list to fill.

In order not to mess with me, let's see the code:

public ArrayList<Sector> obtenerTotalSubsectores(ArrayList<Sector> sectores) {
    sectores.add(this);
    if (this.getSectores() != null) {
        for (Sector sector1 : this.getSectores()) {
            sector1.obtenerTotalSubsectores(sectores);
        }
    }
    return sectores;
}

Now yes that you can add this since the recursion is running correctly from the currently processed sector, downloading the method of an attribute and clarifying the code (although increasing the abstraction)

The same modified main would look like this:

ArrayList<Sector> sectores = new ArrayList<Sector>();
s1.obtenerTotalSubsectores(sectores);


System.out.println("TOTAL SECTORES EN EL " + s1.getNumero());
for (Sector s : sectores) {
    System.out.println(s.toString());
}

sectores.clear();
s2.obtenerTotalSubsectores(sectores);

System.out.println("\n\nTOTAL SECTORES EN EL " + s2.getNumero());
for (Sector s : sectores) {
    System.out.println(s.toString());
}

And would give us the same result:

TOTAL SECTORES EN EL 100
Sector [numero=100, denominacion=sales, tipo=sales, sectores=[Sector [numero=101, denominacion=minor sales, tipo=minor, sectores=[]], Sector [numero=102, denominacion=mayor sales, tipo=mayor, sectores=[Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]]], Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]]]
Sector [numero=101, denominacion=minor sales, tipo=minor, sectores=[]]
Sector [numero=102, denominacion=mayor sales, tipo=mayor, sectores=[Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]]]
Sector [numero=102, denominacion=lala sales, tipo=lalala, sectores=[]]
Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]
Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]


TOTAL SECTORES EN EL 200
Sector [numero=200, denominacion=Sistemas, tipo=sistemas, sectores=[Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]]]
Sector [numero=201, denominacion=Soporte Técnico, tipo=soporte, sectores=[]]
 2
Author: Jordi Castilla, 2020-06-11 10:54:57