While working with Streams in Java 11
, I noticed the following situation. I'm trying to use the Stream API in two different ways on a non-null list.
First way:
Collection<Object> categoryIds = List.of(1L, 2L, 3L, 4L);
List<String> nullable = Stream.ofNullable(categoryIds)
.map(Object::toString)
.collect(Collectors.toList());
Second way:
Collection<Object> categoryIds = List.of(1L, 2L, 3L, 4L);
List<String> nullable = categoryIds.stream()
.map(Object::toString)
.collect(Collectors.toList());
The two ways I tried lead to two different results. The resulting list of the first way is a string containing a single element. This string is: "[1, 2, 3, 4]"
The second way gives the desired and expected results. Returns a result list with 4 elements: "1", "2", "3", "4"
.
Is this behavior expected? Or is it a problem?
Stream.ofNullable you are creating a Stream
object with single element or empty Stream for null object
Returns a sequential Stream containing a single element, , if non-null, otherwise returns an empty Stream.
If you want to get the same output using Stream.ofNullable
you need to flatten the list using flatMap
List<String> nullable = Stream.ofNullable(categoryIds)
.flatMap(List::stream)
.map(Object::toString)
.collect(Collectors.toList());
Collection.stream - it creates the stream object with collection elements in sequential order
Returns a sequential Stream with this collection as its source.
And the Collection.stream
is equivalent to stream.of(T... values) method
List<String> nullable = Stream.of(1L, 2L, 3L, 4L) // or categoryIds.stream()
.map(Object::toString)
.collect(Collectors.toList());