I expected to be able to use Stream::flatMap like this
public static List duplicate(String s) {
List l = new ArrayList
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>>.
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());