Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams - collect and stream map of lists

I have a Map of Lists, and would like to collect all the values and then stream on the collected List, so given:-

Map<LocalDateTime, List<PublicationSession>> effectiveDatePublicationMap;

Below works / shows what I want to do with iteration but I want to do this all in streams, rather than creating an intermediate list using iteration:-

List< PublicationSession> publicationsToFilter = new ArrayList<>();
for (List< PublicationSession> sessions : effectiveDatePublicationMap.values()) {
    publicationsToFilter.addAll(sessions);
}

Collection< PublicationSession > wantedPublications = publicationsToFilter.stream()
            .filter(pub -> PublicationStatus.valueOf(pub.getPublishStatus()) == PublicationStatus.COMPLETE)
            .sorted(Comparator.comparing(PublicationSession::getCreateTime))
            .collect(toMap(p -> p.getPublicationSession().getEffDateTime(), UnaryOperator.identity(), PICK_LATEST))
            .values();

So I wanted to stream the map of lists all into one lists, then work on that sublist in one stream rather than having to do the above in two statements (ie build up the list by iteration, then do the streaming to filter / sort and collect.

I have so far failed to do so, when I try and stream / collect the map I get compile issues. Could anyone show how to do the above in one step, without having to do iteration then streaming?

like image 605
sub123 Avatar asked Dec 03 '25 14:12

sub123


2 Answers

It looks like all you need is flatMap the values of the original Map and then continue processing as you currently do:

Collection< PublicationSession > wantedPublications = 
    effectiveDatePublicationMap.values() // Collection<List<PublicationSession>>
                               .stream() // Stream<List<PublicationSession>>
                               .flatMap(list->list.stream()) // Stream<PublicationSession>
                               .filter(pub -> PublicationStatus.valueOf(pub.getPublishStatus()) == PublicationStatus.COMPLETE)
                               .sorted(Comparator.comparing(PublicationSession::getCreateTime))
                               .collect(toMap(p -> p.getPublicationSession().getEffDateTime(), UnaryOperator.identity(), PICK_LATEST))
                               .values();
like image 172
Eran Avatar answered Dec 06 '25 02:12

Eran


To obtain the same result of your iterative code

List< PublicationSession> publicationsToFilter = new ArrayList<>();
for (List< PublicationSession> sessions : effectiveDatePublicationMap.values()) {
    publicationsToFilter.addAll(sessions);
}

with streams you first have to use flatMap to transoform your stream of List<PublicationSession> in a stream of PublicationSession, and then collect all of them in a list with collect(Collectors.toList())

List<PublicationSession> publicationsToFilter = effectiveDatePublicationMap.values()
                                                   .flatMap(Collection::stream)
                                                   .collect(Collectors.toList());

Before collecting the result, you can filter or sort as you wish.

like image 34
SimoV8 Avatar answered Dec 06 '25 04:12

SimoV8