Collectors.toMap only if optional value is present

CuriousCoder :

I have a list of languages like english, french, etc. I also have a list of words like apple, orange, etc. For each word, I want to create a map that looks like this:

Map map = {english = apple, italian = mela}

In order to get the translatedWord, I have a function that returns an optional. Signature of the method looks like this:

Optional<TranslatedWord> getTranslatedWord(String word, Language language);

This is the code I have written to collect the words into a map

List<Language> languages = {english, italian, french};
for(String w : words) {
   Map<Language, TranslatedWord> map = languages.stream().collect(Collectors.ToMap(language -> language,
      language -> getTranslatedWord(w, language));

   doSomethingWithThisMap(map);
}

The problem is getTranslatedWord() returns an Optional. I need to collect it into the Map only if the optional has a value in it. How can I do this?

Andy Turner :

Filter before you collect:

Map<Language, TranslatedWord> map =
    languages.stream()
        .map(lang -> new AbstractMap.SimpleEntry<>(lang, getTranslatedWord(w, lang)))
        .filter(e -> e.getValue().isPresent())
        .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get()));

However, streams don't add all that much value here. You could just use a loop:

Map<Language, TranslatedWord> map = new HashMap<>();
for (Language lang : languages) {
  getTranslatedWord(w, lang)
      .ifPresent(t -> map.put(lang, t));
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=88463&siteId=1