Akash Sharma
Akash Sharma

Reputation: 356

Creating a map from nested lists

Suppose there are 3 classes:

class Level1 {
    int idLevel1;
    List<Level2> level2list;    
}

class Level2 {
    int idLevel2;
    List<Level3> level3list;    
}   

class Level3 {  
    int idLevel3;
    String name;
}   

Suppose there is a List of Level1 objects called initial state

List<Level1> initialList = new ArrayList<>();

I want to create a map from initialList where:

 - Key: is idLevel1
 - Value: is list of all idLevel3 , corresponding to idLevel1

I am able to achieve this using for loops, but I want to achieve this in a more elegant way using Java 8 features (streams and the functions). I tried using Collectors.toMap() also tried grouping but I am unable to get the desired map.

Upvotes: 0

Views: 1619

Answers (3)

lczapski
lczapski

Reputation: 4120

Similar approach to others:

Map<Integer, List<Integer>> map = initialList.stream()
        .collect(Collectors.toMap(Level1::getIdLevel1,
                lv1 -> lv1.getLevel2list().stream()
                        .flatMap(lv2 -> lv2.getLevel3list().stream().map(Level3::getIdLevel3))
                        .collect(Collectors.toList())));

I added getters in yout classes and change one name from List<Level3> level2list; to List<Level3> level3list;:

class Level1 {
    int idLevel1;
    List<Level2> level2list;

    public int getIdLevel1() {
        return idLevel1;
    }

    public List<Level2> getLevel2list() {
        return level2list;
    }
}

class Level2 {
    int idLevel2;
    List<Level3> level3list;

    public List<Level3> getLevel3list(){
        return level3list;
    }
}

class Level3 {
    int idLevel3;
    String name;

    public int getIdLevel3() {
        return idLevel3;
    }
}

Upvotes: 2

WJS
WJS

Reputation: 40034

By corresponding to idLevel1 I made the assumption that you wanted a list of all idlevel3 that were in the chain for the a particular idLevel1

So there could be a list of level3 ids for some level1 id and a different list of level3 ids for a different level1 id.

Based on that, this is what I came up with.

        Map<Integer, List<Integer>> map = initialList
                .stream()
                .collect(Collectors
                        .toMap(lv1 -> lv1.idLevel1,
                                lv1 -> lv1.level2list
                                        .stream()
                        .flatMap(lv2 -> lv2.level3list
                                .stream())
                        .map(lv3 -> lv3.idLevel3)
                        .collect(Collectors.toList())));

Upvotes: 1

Maxdola
Maxdola

Reputation: 1650

I have this which is valid but I have no data to test it so pls test it and give me feedback :).

Map<Integer, List<String>> map = 
        initialList.stream()
                .collect(Collectors.toMap(f -> f.idLevel1,
                f -> f.level2list.stream()
                .flatMap(f2 -> f2.level2list.stream())
                .collect(Collectors.toList()).stream()
                .filter(f3 -> f3.idLevel3 == f.idLevel1)
                .map(f3 -> f3.name).collect(Collectors.toList())));

Upvotes: 0

Related Questions