JReynolds
JReynolds

Reputation: 59

Java streams getting a List from map of maps

I have the following variable declaration

Map<EventType<? extends Event>, Map<EventSource, List<EventHandler<? super Event>>>> eventHandlers;

Using java streams I would like to filter this map first on eventType then filter on eventSource ending up with a List.

How do I go about doing this using java streams, I have tried several different approaches but without success. the implementation I have thus far is

List <Object> something = eventHandlers.entrySet().stream().filter(entry
                        -> entry.getKey() == event.eventType || event.eventType.isSubType(entry.getKey())
                ).map(Map.Entry::getValue).collect(Collectors.toList());

But I just end with a List<Map<EventSource, List<EventHandler<? super Event>>>>

How do I achieve this, any help or pointers will be appreciated.

Many thanks

Upvotes: 1

Views: 207

Answers (1)

njzk2
njzk2

Reputation: 39386

Expanding on my comment, something like this (written without compiler, so there might be some errors) should work:

List<EventHandler<? super Event>> output = eventHandlers
    .entrySet()
    .stream()
    .filter(entry -> entry.getKey() == event.eventType || event.eventType.isSubType(entry.getKey()))
    .map(Map.Entry::getValue)
    .map(Map::entrySet)
    .flatMap(Set::stream)
    .filter(entry -> entry.getKey() == event.eventSource) // ? Modify the filter on event source according to your needs
    .map(Map.Entry::getValue)
    .flatMap(List::stream)
    .collect(Collectors.toList());

Note that you can shorten a bit, using lambdas instead of function references:

List<EventHandler<? super Event>> output = eventHandlers
    .entrySet()
    .stream()
    .filter(entry -> entry.getKey() == event.eventType || event.eventType.isSubType(entry.getKey()))
    .flatMap(entry -> entry.getValue().entrySet().stream())
    .filter(entry -> entry.getKey() == event.eventSource) // ? Modify the filter on event source according to your needs
    .flatMap(entry -> entry.getValue().stream())
    .collect(Collectors.toList());

Upvotes: 1

Related Questions