问题
Using Stream.of
to create generic streams is very convenient, but what if I want to create a Stream<String[]>
of only one element?
Let’s say I have:
String[] tropicalFruits = new String[] {"pineapple", "banana", "mango"};
String[] fruits = new String[] {"melon", "peach", "apple"};
Then Stream.of(tropicalFruits, fruits)
produces a Stream<String[]>
of two elements. How can I achieve the same for a stream of a single element? If I try:
Stream<String[]> fruityStream = Stream.of(tropicalFruits);
I get:
Error: incompatible types: inference variable
T
has incompatible bounds
equality constraints:java.lang.String[]
lower bounds:java.lang.String
Stream<String[]> fruityStream = Stream.of(fruits); ^---------------^
I’ve googled for this and searched in SO but I got nothing. It seems to me that it’s not a very unusual or esoeteric problem, so it’s kind of surprising I didn’t get any answers (or I’m not searching with the right keywords).
回答1:
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[]>
.
回答2:
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)));
回答3:
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[] {});
来源:https://stackoverflow.com/questions/48625611/how-can-i-create-a-streamstring-with-only-one-element-with-stream-of