Reputation: 1600
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?
Upvotes: 6
Views: 1905
Reputation: 140534
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));
}
Upvotes: 8
Reputation: 609
Just put a filter before collecting into map
for(String w : words) {
Map<Language, TranslatedWord> map = languages.stream()
.map(lang -> new AbstractMap.SimpleEntry<>(lang, getTranslatedWord(w, lang)))
.filter(e -> e.getValue().isPresent())
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().get()));
doSomethingWithThisMap(map);
}
Upvotes: -1