问题
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
Thas incompatible bounds
equality constraints:java.lang.String[]
lower bounds:java.lang.StringStream<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