How can I create a Stream<String[]> with only one element with Stream.of?

你离开我真会死。 提交于 2019-12-22 01:33:47

问题


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:

  1. To specify a type argument of the method explicitly to use the first signature.
    Stream.<String[]>of(new String[]{}) will produce a Stream<String[]>.
  2. To wrap a T[] value in a T[][] array to use the second signature.
    Stream.of(new String[][]{}) will produce a Stream<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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!