0

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.

7
  • 1
    a series of two flatMap, it seems. Commented Jan 8, 2020 at 21:34
  • Show us your attempt - aside of giving an answer, we can also help you based on your attempt :) Commented Jan 8, 2020 at 22:05
  • Elegant does not necessarily mean best. Commented Jan 9, 2020 at 1:31
  • Shouldn't the level2List in the Level2 class definition really be level3List? Commented Jan 9, 2020 at 1:50
  • @WJS yes you are right, it should be level3List Commented Jan 9, 2020 at 22:48

3 Answers 3

2

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;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

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())));

3 Comments

Is this not same as the existing answer?
@Naman. No. I interpreted the requirement differently and did not do any filtering by comparing level1ID to level3ID as it made no sense to me (I could be wrong but I figure the OP will let me know).
And that could have been worth a comment rather than an answer. Since the type collected in the existing answer still logically remains same.
0

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())));

1 Comment

your approach was almost right, I think filter is not needed. Thank you for trying to help me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.