Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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, List<String>> listOfLists = new HashMap<>();

Now using stream I want to fill like:

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

My UNFINISHED (that's the question) code is:

listEntityComposite.stream()forEach(entityComposite {
        // How create a list according entityComposite.getId.getFirstId()?
        listOfLists.put(entityComposite.getId.getFirstId(), .... )
    });
like image 308
joseluisbz Avatar asked Dec 14 '18 20:12

joseluisbz


People also ask

Can we use forEach in streams Java?

Stream forEach() method in Java with examplesStream forEach(Consumer action) performs an action for each element of the stream. Stream forEach(Consumer action) is a terminal operation i.e, it may traverse the stream to produce a result or a side-effect.

What is difference between list forEach and list Stream () forEach?

The reason for the different results is that forEach() used directly on the list uses the custom iterator, while stream(). forEach() simply takes elements one by one from the list, ignoring the iterator.

How can I turn a list of lists into a list in Java 8?

Here is the simple, concise code to perform the task. // listOfLists is a List<List<Object>>. List<Object> result = new ArrayList<>(); listOfLists. forEach(result::addAll);


1 Answers

collect is a more suitable terminal operation for generating an output Map than forEach.

You can use collect() with Collectors.groupingBy:

Map<Long, List<String>> listOfLists =
    listEntityComposite.stream()
                       .collect(Collectors.groupingBy(e -> e.getId().getFirstId(),
                                                      Collectors.mapping(EntityComposite::getSecond,
                                                                         Collectors.toList());

Collectors.groupingBy with a single argument (just e -> e.getId().getFirstId()) would generate a Map<Long,List<EntityComposite>>.

Chaining to it Collectors.mapping() maps each EntityComposite instance to the corresponding getSecond() String, as required.

like image 122
Eran Avatar answered Sep 21 '22 13:09

Eran