5

I have a stream of elements. I want to map each element to two different elements of the same type so that my stream will be two times longer in consequence. I did this by concatenating two streams, but I'm wondering is it possible to do this simpler? What I've done so far:

private List<String> getTranslationFilesNames() {
return Stream.concat(SUPPORTED_LANGUAGES.stream()
                .map(lang -> PATH_TO_FILES_WITH_TRANSLATIONS_1 + lang + FILE_EXTENSION),
        SUPPORTED_LANGUAGES.stream()
                .map(lang -> PATH_TO_FILES_WITH_TRANSLATIONS_2 + lang + FILE_EXTENSION))
        .collect(Collectors.toList());
}

I don't find this solution very elegant. Is there better approach to achieve the same effect?

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
k13i
  • 4,011
  • 3
  • 35
  • 63

2 Answers2

5

If you don't care about the order, you can map each element to a pair of elements with flatMap:

private List<String> getTranslationFilesNames() {
    return SUPPORTED_LANGUAGES.stream()
            .flatMap(lang -> Stream.of(PATH_TO_FILES_WITH_TRANSLATIONS_1 + lang + FILE_EXTENSION,
                                       PATH_TO_FILES_WITH_TRANSLATIONS_2 + lang + FILE_EXTENSION)),
            .collect(Collectors.toList());
}
Eran
  • 387,369
  • 54
  • 702
  • 768
4

Instead of creating a combined Stream, you can simply use the #flatMap operator to duplicate the input elements (note that this may be a suitable solution only if the elements order does not matter):

private List<String> getTranslationFilesNames() {
  return SUPPORTED_LANGUAGES.stream()
      .flatMap(s -> Stream.of(
              PATH_TO_FILES_WITH_TRANSLATIONS_1 + s + FILE_EXTENSION,
              PATH_TO_FILES_WITH_TRANSLATIONS_2 + s + FILE_EXTENSION
          )
      )
      .collect(Collectors.toList());
}
tmarwen
  • 15,750
  • 5
  • 43
  • 62