mfullstackdev
mfullstackdev

Reputation: 55

iterate over nested list (any depth)

How iterate over nested list (any depth)? I have the following structure

Com 1
    Com 2
        Com 55
            Com 551
            Com 552
        Com 56
        Com 57
            Com 66
            Com 67
                Com 99
    Com 3
        Com 33
        Com 34
        Com 35
    Com 4
        Com 41
        Com 42
            Com 421
            Com 423

I want export data to txt file with hiearchy. How detect when should I add "space" to make hierarchy?

@Entity
public class Company {
    private Long id;
    private String name;
    private List<Company> children = new ArrayList<>();


    public Company() {
    }
    
    //getters and setters
    
    public Stream<Company> flattened() {
        return Stream.concat(
                Stream.of(this),
                children.stream().flatMap(Company::flattened));
    }
}

Upvotes: 5

Views: 718

Answers (3)

Sergey Afinogenov
Sergey Afinogenov

Reputation: 2212

Make flattenedWithLevel method to generate Stream of Pairs (Company and it's depth):

public Stream<Pair<Integer, Company>> flattenedWithDepth(int depth) {
    return Stream.concat(
            Stream.of(new Pair<>(depth, this)),
            children.stream().flatMap(c -> c.flattenedWithDepth(depth+1)));
} 

Then you can print all stream elements in a way you need:

comp.flattenedWithDepth(1)
    .forEach(p ->
        {for (int i=0; i < p.getKey(); i++) 
            System.out.print(" ");
         System.out.println("Com " + p.getValue().getId());
        });  

Upvotes: 0

samabcde
samabcde

Reputation: 8114

Stream approach

@Entity
public class Company {
...
    public Stream<String> indentedNames() {
        return indentedNames(0);
    }

    private Stream<String> indentedNames(int level) {
        return Stream.concat(
                Stream.of(" ".repeat(level) + this.getName()),
                children.stream().flatMap(c -> c.indentedNames(level + 1)));
    }
...
}
    public static void main(String[] args) {
        Company company1 = new Company("1");
        Company company2 = new Company("2");
        Company company3 = new Company("3");
        Company company4 = new Company("4");
        Company company5 = new Company("5");
        Company company6 = new Company("6");
        Company company7 = new Company("7");
        company1.setChildren(List.of(company2, company3));
        company2.setChildren(List.of(company4, company5));
        company4.setChildren(List.of(company6, company7));
        company1.indentedNames().forEach(System.out::println);
    }

Upvotes: 0

Noixes
Noixes

Reputation: 1178

Assuming that you dont have cyclic company references (so no child company points to one of its parents) you can do this recursivly like this:

public static void print(Company company, int depth) {
        for (int i = 0; i < depth; i++) {
            System.out.print(" ");
        }
        System.out.println(company.getName());
        for (Company child : company.getChildren()) {
            print(child, depth + 1);
        }
}

Upvotes: 2

Related Questions