如何使用Stream.of只创建一个Stream <String []>?

Alf*_*Alf 20 java type-inference variadic-functions java-8 java-stream

使用Stream.of创建通用流非常方便,但是如果我想创建一个Stream<String[]>只有一个元素呢?

比方说我有:

String[] tropicalFruits = new String[] {"pineapple", "banana", "mango"};
String[] fruits = new String[] {"melon", "peach", "apple"};
Run Code Online (Sandbox Code Playgroud)

然后Stream.of(tropicalFruits, fruits)产生Stream<String[]>两个元素.如何为单个元素的流实现相同的功能?如果我尝试:

Stream<String[]> fruityStream = Stream.of(tropicalFruits);
Run Code Online (Sandbox Code Playgroud)

我明白了:

错误:不兼容的类型:推理变量T具有不兼容的边界
相等约束:java.lang.String[]
下限:java.lang.String

Stream<String[]> fruityStream = Stream.of(fruits);
                                 ^---------------^
Run Code Online (Sandbox Code Playgroud)

我用Google搜索并搜索了但是我什么也没得到.在我看来,这不是一个非常不寻常的或esoeteric问题,所以有点令人惊讶我没有得到任何答案(或者我没有用正确的关键词搜索).

And*_*lko 28

Stream<String[]> stream = Stream.<String[]>of(tropicalFruits);
Run Code Online (Sandbox Code Playgroud)

要么

Stream<String[]> stream = Stream.of(new String[][]{tropicalFruits});
Run Code Online (Sandbox Code Playgroud)

说明

要产生一个Stream<T>,Stream.of要么采取TT....
一个T[]参数完全适用于第二签名.
因此,传递一个String[]调用Stream.of(String...)版本.

要改变这种行为,我们需要提供一些关于T(1)的额外信息或更清楚地定义它(=明确地)(2).

我想到了两个想法:

  1. 要明确指定方法的类型参数以使用第一个签名.
    Stream.<String[]>of(new String[]{})会产生一个Stream<String[]>.
  2. T[]值包装在T[][]数组中以使用第二个签名.
    Stream.of(new String[][]{})会产生一个Stream<String[]>.

  • 在[`List.of(E ...)`方法的javadoc]中(https://docs.oracle.com/javase/9​​/docs/api/java/util/List.html#of-E ... - ),这种情况由API覆盖注意:*此方法也接受单个数组作为参数.结果列表的元素类型将是数组的组件类型,列表的大小将等于数组的长度.要使用作为数组的单个元素创建列表,请执行以下操作:*`String [] array = ...; List <String []> list = List.(String)的字符串[]>;`.我认为这个API注释也应该添加到`Stream.of(E ...)`方法的文档中. (11认同)
  • 我喜欢Jacob和Eugene的另外两个答案,但我认为第二个解决方案是最正确的,因为它不需要创建任何额外的数组或列表. (5认同)
  • 哦拍更多类型信息添加真棒!你应该解释我猜的第一个:) (3认同)
  • @FedericoPeraltaSchaffner非常有趣,*通常*添加更多类型信息,因为目标是通过这种方式推断的; 但这里实际上是选择一个重载方法.优秀评论! (3认同)
  • 比我的答案更好!第一个看起来像是利用varargs,这很棒. (2认同)

Eug*_*ene 6

这个 Stream<String[]> fruittyStream = Stream.of(tropicalFruits);

调用var-arg方法Stream.of.

我可以想到这个解决方法:

List<String> list = Arrays.asList("one");
Stream.of(list)
      .map(x -> x.toArray(new String[1]));
Run Code Online (Sandbox Code Playgroud)

或者你可以稍微改变一下var-args方法:

 Stream.of(tropicalFruits, null)
       .filter(Objects::nonNull)
       .forEach(x -> System.out.println(Arrays.toString(x)));
Run Code Online (Sandbox Code Playgroud)


Jac*_* G. 5

通过Stream#of单一调用T[],Java默认为vararg工厂方法,创建一个Stream<T>而不是一个Stream<T[]>.要Stream<T[]>使用单个元素创建一个元素,您可以创建一个Stream<T[]>包含多个元素并调用limit(1),或者对第二个元素使用虚拟数组:

Stream<String[]> stream = Stream.of(tropicalFruits, fruits).limit(1);

Stream<String[]> stream = Stream.of(tropicalFruits, new String[] {});
Run Code Online (Sandbox Code Playgroud)