Collectors.toMap, только если присутствует необязательное значение

У меня есть список таких языков, как английский, французский и т. д. У меня также есть список таких слов, как яблоко, апельсин и т. д. Для каждого слова я хочу создать карту, которая выглядит следующим образом:

Карта карта = {английский = яблоко, итальянский = мела}

Чтобы получить переведенное слово, у меня есть функция, которая возвращает необязательный параметр. Сигнатура метода выглядит так:

Optional<TranslatedWord> 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() возвращает необязательное значение. Мне нужно собрать его на карту только в том случае, если в нем есть значение. Как я могу это сделать?


person CuriousCoder    schedule 03.06.2019    source источник


Ответы (2)


Отфильтруйте, прежде чем собирать:

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));
}
person Andy Turner    schedule 03.06.2019

Просто поставьте фильтр перед сбором на карту

    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);
    }
person Arvind Kumar    schedule 03.06.2019
comment
Непосредственная проблема, которая возникает здесь, заключается в том, что getTranslatedWord вызывается дважды в одном конвейере. - person Naman; 03.06.2019
comment
да. это очень серьезное беспокойство. Я думаю, что другой ответ @Andy Terner хорош, кто сопоставляет данные перед фильтрацией. - person Arvind Kumar; 03.06.2019