How can I create a Stream<String[]> with only one element with Stream.of?
Solution
Stream<String[]> stream = Stream.<String[]>of(tropicalFruits);
or
Stream<String[]> stream = Stream.of(new String[][]{tropicalFruits});
Explanation
To produce a Stream<T>
, Stream.of
takes either T
or T...
.
A T[]
parameter perfectly applies to the second signature.
Therefore, passing a String[]
invokes the Stream.of(String...)
version.
To change this behaviour, we need to provide some extra information about T
(1) or define it more clearly (=unambiguously) (2).
There are two ideas came to my mind:
- To specify a type argument of the method explicitly to use the first signature.
Stream.<String[]>of(new String[]{})
will produce aStream<String[]>
. - To wrap a
T[]
value in aT[][]
array to use the second signature.
Stream.of(new String[][]{})
will produce aStream<String[]>
.
This Stream<String[]> fruittyStream = Stream.of(tropicalFruits);
calls the var-arg method of Stream.of
.
I can think of this workaround:
List<String> list = Arrays.asList("one");
Stream.of(list)
.map(x -> x.toArray(new String[1]));
Or you can call the var-args method a bit differently:
Stream.of(tropicalFruits, null)
.filter(Objects::nonNull)
.forEach(x -> System.out.println(Arrays.toString(x)));
By calling Stream#of
with a single T[]
, Java defaults to the vararg factory method, creating a Stream<T>
rather than a Stream<T[]>
. To create a Stream<T[]>
with a single element, you can either create a Stream<T[]>
with multiple elements and call limit(1)
, or use a dummy array for the second element:
Stream<String[]> stream = Stream.of(tropicalFruits, fruits).limit(1);
Stream<String[]> stream = Stream.of(tropicalFruits, new String[] {});