Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating nested maps with nested properties from List, stream, Java 8

I made this question stream creating List of List (nested List) using forEach, Java 8

class EntityCompositeId {
    private Long firstId;
    private Long secondId;
    // getter & setter...
}

class EntityComposite {
    private EntityCompositeId id;
    private String first;
    private String second;
    // getter & setter...
}

List<EntityComposite> listEntityComposite = ....
Supose this content

1, 1, "firstA", "secondBirdOne"
1, 2, "firstA", "secondBirdTwo"
1, 3, "firstA", "secondBirdThree"

2, 1, "firstB", "secondCatOne"
2, 2, "firstB", "secondCatTwo"
2, 3, "firstB", "secondCatThree"

3, 1, "firstC", "secondDogOne"
3, 2, "firstC", "secondDogTwo"
3, 3, "firstC", "secondDogThree"

Map<Long, Map<Long, String>> listOfLists = new HashMap<>();

Now using stream I want to fill like:

 1 -> {1 ->"secondBirdOne", 2 -> "secondBirdTwo", 3 -> "secondBirdThree"}
 2 -> {1 ->"secondCatOne", 2 -> "secondCatTwo", 3 -> "secondCatThree"}
 3 -> {1 ->"secondDogOne", 2 -> "secondDogTwo", 3 -> "secondDogThree"}

My NOT functional code was:

    Map<Long, Map<Long, String>> listaMunDepa = listEntityComposite.stream()
        .collect(Collectors.groupingBy(
            e -> e.getId().getFirstId(),
            Collectors.toMap(f -> f.getId().getSecondId(), Function.identity()))
    );

second Try

    Map<Long, Map<Long, String>> listaMunDepa = listEntityComposite.stream()
        .collect(Collectors.groupingBy(
            e -> e.getId().getFirstId(),
            Collectors.groupingBy(EntityComposite::getId::getSecondId, EntityComposite::getSecond)) // How change this line
    );
like image 445
joseluisbz Avatar asked Dec 14 '18 22:12

joseluisbz


1 Answers

You're really close, instead of passing Function.identity, you should pass EntityComposite::getSecond

listEntityComposite.stream()
           .collect(groupingBy(e -> e.getId().getFirstId(),
                  toMap(f -> f.getId().getSecondId(), EntityComposite::getSecond)));

because you supplied Function.identity the result was Map<Long, Map<Long, EntityComposite>>, so as shown above, you'll simply need to extract the getSecondId for the valueMapper function supplied to toMap hence yielding a Map<Long, Map<Long, String>>.

like image 85
Ousmane D. Avatar answered Oct 31 '22 05:10

Ousmane D.