只有当可选值存在时,Collectors.toMap 才能使用。

4
我有一份语言列表,例如英语、法语等。我还有一个单词列表,例如苹果、橘子等。对于每个单词,我想创建一个像这样的映射:
Map map = {english = apple, italian = mela}
为了获得翻译后的单词,我有一个返回Optional的函数。该方法的签名如下:
Optional getTranslatedWord(String word, Language language);
这是我编写的代码,将这些单词收集到一个映射中:
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);
}

问题是getTranslatedWord()返回一个Optional。如果这个optional有值,我需要将其收集到Map中。我该如何操作?
2个回答

7

在收集之前进行筛选:

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()));

然而,在这里,流并没有增加太多价值。您可以使用循环来完成:

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

-1

在收集到映射之前,只需放置一个过滤器即可。

    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);
    }

这里立即引起的关注是,在单个管道中调用了两次 getTranslatedWord - Naman
1
是的,这是非常有效的关注点。我认为另一个回答者@Andy Terner的答案很好,他在过滤之前对数据进行了映射。 - Arvind Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接