如何创建Stream <string []>只有一个元素与Stream.of?

时间:2018-02-05 15:13:58

标签: java java-8 java-stream variadic-functions type-inference

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

让我说我有:

String[] tropicalFruits = new String[] {"pineapple", "banana", "mango"};
String[] fruits = new String[] {"melon", "peach", "apple"};

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

Stream<String[]> fruityStream = Stream.of(tropicalFruits);

我明白了:

  

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

Stream<String[]> fruityStream = Stream.of(fruits);
                                 ^---------------^

我已经用Google搜索并搜索了,但我一无所获。在我看来,这不是一个非常不寻常或不太具体的问题,所以我没有得到任何答案(或者我没有用正确的关键词搜索),这有点令人惊讶。

3 个答案:

答案 0 :(得分:29)

解决方案

Stream<String[]> stream = Stream.<String[]>of(tropicalFruits);

Stream<String[]> stream = Stream.of(new String[][]{tropicalFruits});

说明

要生成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[]>

答案 1 :(得分:6)

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

调用Stream.of的var-arg方法。

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

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

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

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

答案 2 :(得分:5)

通过使用单个Stream#of调用T[],Java默认为vararg factory method,创建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[] {});