如何从数组创建流?

ada*_*ubi 127 java arrays java-8 java-stream

目前,每当我需要从数组创建流时,我都会这样做

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();
Run Code Online (Sandbox Code Playgroud)

是否有一些从数组创建流的直接方法?

sol*_*4me 192

你可以使用Arrays.stream例如

Arrays.stream(array);
Run Code Online (Sandbox Code Playgroud)

您也可以Stream.of像@fge一样使用,看起来像

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}
Run Code Online (Sandbox Code Playgroud)

但是注意Stream.of(intArray)将返回Stream<int[]>,但是如果你传递一个类型的数组,Arrays.stream(intArr)它将返回.因此简而言之,对于基元类型,您可以观察两种方法之间的差异IntStreamint[]

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 
Run Code Online (Sandbox Code Playgroud)

将原始数组传递给时Arrays.stream,将调用以下代码

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}
Run Code Online (Sandbox Code Playgroud)

当您传递原始数组时,Stream.of将调用以下代码

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }
Run Code Online (Sandbox Code Playgroud)

因此,你得到不同的结果.

更新:如Stuart Marks所述,注释子范围超载Arrays.stream比使用更好,Stream.of(array).skip(n).limit(m)因为前者导致SIZED流,而后者则不然.原因是limit(m)不知道大小是m还是小于m,而是进行Arrays.stream范围检查并知道流的确切大小您可以读取Arrays.stream(array,start,end) 此处返回的流实现的源代码,而对于返回的流实现Stream.of(array).skip().limit()则是在这种方法中.

  • 这个答案更好,因为`Arrays.stream`具有原始数组的所有重载情况.即`Stream.of(new int [] {1,2,3})`将给你一个`Stream <int []>`而``Arrays.stream`会给你一个`IntStream`,这可能就是你了想.所以+1 (9认同)
  • 对于有兴趣看到这个小戏剧结束的读者,`Arrays.stream(array,start,end)`返回一个`Stream`,其实现是[here](http://grepcode.com/file/repository.grepcode. com/java/root/jdk/openjdk/8-b132/java/util/stream/ReferencePipeline.java #ReferencePipeline.Head),而`Stream.of(array).skip().limit()`返回一个`Stream `其实现在[此方法]中(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/stream/SliceOps.java#SliceOps. makeRef%28java.util.stream.AbstractPipeline%2Clong%2Clong%29). (6认同)
  • @Dima"Arrays.stream"的子范围重载优于使用`Stream.of(array).skip(n).limit(m)`,因为前者导致SIZED流而后者不导致.原因是`limit(m)`不知道大小是"m"还是小于"m",而"Arrays.stream"进行范围检查并知道流的确切大小. (4认同)
  • @Dima我想这是一个品味问题.我的意思是更好,在某种意义上,"Stream.of"可以给你一些惊喜(就像你用原始数组调用`Arrays.asList`并且人们期望`List <Integer>`返回):-) (3认同)
  • `Arrays.stream`支持流式传输一系列数组,`IntStream.of`没有.相比之下,如果你想要一个大小为1的`Stream <int []>`,`Stream.of`是更好的选择...... (3认同)
  • @Dima你看错了地方. (3认同)
  • @Dima我正在回答_"如何从数组中创建一个流"_我的例子被简化为适合注释(在这种情况下是的,我也称之为'of`的值),但你可以在想要在Stream中转换它之前定义了int数组.这就是为什么Arrays.stream更适合将数组转换为Stream(我的例子是显示两者之间的差异,这在答案中没有提到). (2认同)
  • @Dima如果你以两种不同的方式创建流,获得它们的分裂器,并查看spliterator实现及其特征,你会发现它们有所不同.请自己尝试一下. (2认同)

fge*_*fge 43

替代@ sol4me的解决方案:

Stream.of(theArray)
Run Code Online (Sandbox Code Playgroud)

这和Arrays.stream()它之间的区别在于:如果你的数组是原始类型,那确实会有所不同.例如,如果你这样做:

Arrays.stream(someArray)
Run Code Online (Sandbox Code Playgroud)

这里someArray是一个long[],它会返回一个LongStream.Stream.of()另一方面,将Stream<long[]>使用单个元素返回a .

  • @Dima:这是一个偏好问题.这些差异非常微小,根本无关紧要.更具体地说:几个字符的差异******.标准库*中的包*的另一个导入是******.实际上,手动创建一个数组而不是一个varargs重载是没有**. (3认同)
  • 好吧,至于溪流,方便!在处理原始数组时,当你有`Arrays.stream()`时,不需要调用`*Stream.of()`.至于数组不是真正的对象,嗯,这是Java,自1.0以来就是这样,所以处理它; 沉思于此对此毫无帮助 (2认同)
  • @Dima等你的; _you_认为`Arrays.stream()`不方便,_I_认为方便.说够了. (2认同)
  • @Dima是的,我发现你的论点是`*Stream.of()`更方便谬误; 因为这是_preferences_的问题.对于这种情况,我更喜欢`Arrays.stream()`,这使得`Stream.of()`更方便(Peano代数)的一般规则是错误的. (2认同)

Dim*_*ima 13

Stream.of("foo", "bar", "baz")
Run Code Online (Sandbox Code Playgroud)

或者,如果您已经有阵列,也可以这样做

Stream.of(array) 
Run Code Online (Sandbox Code Playgroud)

对于原始类型使用IntStream.ofLongStream.of

  • Java 原语是一种奇怪的野兽。`int[]` 与其他数组不同。它不是“Object[]”的子类,但它_是_“Object”的子类。因此,当您将其传递给“Stream.of”时,它被视为“Object”参数,并且您将获得一个“int[]”流。这是为基元提供专门类的原因之一 - 如果您不从基元数组创建流将非常痛苦。另一个原因是,专用类更加高效,因为它们不需要从装箱中产生“Object”开销(将“int”转换为“Integer”以使其看起来像普通对象)。 (2认同)