Why is this usage of Stream::flatMap wrong?

后端 未结 2 1145
你的背包
你的背包 2020-12-18 18:37

I expected to be able to use Stream::flatMap like this

public static List duplicate(String s) {

    List l = new ArrayList

        
相关标签:
2条回答
  • 2020-12-18 19:20

    The lambda expression in flatMap needs to return a Stream, as can be seen by the argument of flatMap which is of type Function<? super T, ? extends Stream<? extends R>>.

    The following code will compile and run fine:

    listOfStrings.stream()
                 .flatMap(str -> duplicate(str).stream()) // note the .stream() here
                 .collect(Collectors.toList());
    

    because the lambda expression str -> duplicate(str).stream() is of type Function<String, Stream<String>>.

    0 讨论(0)
  • 2020-12-18 19:24

    If you want to duplicate each object in the stream several times, you don't need to waste memory on this with additional ArrayList. There are several shorter and faster alternatives.

    • Generate new stream using Stream.generate, then limit it:

      listOfStrings.stream()
                   .flatMap(str -> Stream.generate(() -> str).limit(2))
                   .collect(Collectors.toList());
      
    • Generate sequence of numbers via IntStream.range and map them to the same string:

      listOfStrings.stream()
                   .flatMap(str -> IntStream.range(0, 2).mapToObj(i -> str))
                   .collect(Collectors.toList());
      
    • Use good old Collections.nCopies:

      listOfStrings.stream()
                   .flatMap(str -> Collections.nCopies(2, str).stream())
                   .collect(Collectors.toList());
      

    If you are sure that you will always duplicate exactly two times, there's the shortest alternative:

    listOfStrings.stream()
                 .flatMap(str -> Stream.of(str, str))
                 .collect(Collectors.toList());
    
    0 讨论(0)
提交回复
热议问题