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\$
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();
    }
    //...
}
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Is it possible to maybe simplify the syntax further using .map(WatchListItem::getInstrument) in the second example? \$\endgroup\$ – BusyAnt Jul 26 at 13:09
  • 1
    \$\begingroup\$ @BusyAnt yes thanks for the hint, I updated it. \$\endgroup\$ – Marc Jul 26 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\$ – vphilipnyc Jul 26 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\$ – RobAu Jul 29 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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