7
\$\begingroup\$

I have the following Java 8+ code (on Java 14). I have a (terminal) forEach call and I am adding each mapped object to a newly created ArrayList.

Is there a more idiomatic way this could be rewritten using Collectors.toList() and potentially flatMap?

public List<SearchSuggestion> suggest() {
   List<Watchlist> watchlists = someService.findAll();
   List<SearchSuggestion> suggestions = new ArrayList<>();

   watchlists.forEach(watchlist -> watchlist.getWatchlistItems()
            .forEach(watchlistItem -> {
                suggestions.add(mapToSearchSuggestion(watchlistItem.getInstrument()));
            })
   );
   return suggestions;
}

private SearchSuggestion mapToSearchSuggestion(Instrument instrument) {
    return SearchSuggestion.builder()
            .symbol(instrument.getSymbol())
            .build();
}
\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

This is one way using flatMap and Collectors.toList():

public List<SearchSuggestion> suggest() {
   return someService.findAll().stream()
            .flatMap(wl->wl.getWatchlistItems().stream())
            .map(wli->mapToSearchSuggestion(wli.getInstrument()))
            .collect(Collectors.toList());
}

However (since this is Code Review) the method mapToSearchSuggestion seems more appropriate to be in the class Instrument. If you can move it there then the function becomes:

public List<SearchSuggestion> suggest() {
    return watchlists.stream()
            .flatMap(wl ->wl.getWatchlistItems().stream())
            .map(WatchlistItem::getInstrument)
            .map(Instrument::mapToSearchSuggestion)
            .collect(Collectors.toList());
}

Instrument class:

public class Instrument {
    //...
    public SearchSuggestion mapToSearchSuggestion() {
        return SearchSuggestion.builder().symbol(getSymbol()).build();
    }
    //...
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Is it possible to maybe simplify the syntax further using .map(WatchListItem::getInstrument) in the second example? \$\endgroup\$
    – BusyAnt
    Jul 26, 2020 at 13:09
  • 1
    \$\begingroup\$ @BusyAnt yes thanks for the hint, I updated it. \$\endgroup\$
    – Marc
    Jul 26, 2020 at 13:57
  • \$\begingroup\$ Thank you! I will try out the first suggestion. The second part may not apply in my case because I will be adding more logic to that method. I feel like the IDE should have an intention to suggest this. \$\endgroup\$ Jul 26, 2020 at 17:04
  • 1
    \$\begingroup\$ @marc I disagree that the method mapToSearchSuggestion should be in Instrument.. Does Instrument even need to know about SearchSuggestion? I think not. Better to extract to a Util/Converter/Builder type of class \$\endgroup\$ Jul 29, 2020 at 15:37

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.