Java 8流的toArray和size参数

Lok*_*oks 1 java lambda java-8 java-stream

我想知道stream().toArray [x - > new Integer [x]]如何知道来自哪个数组的大小?我写了一个片段,其中我创建了一个大小为4的整数列表并过滤了值,并创建了一个长度为过滤流的数组,我无法看到任何方法来获取流的大小.

List<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2);
intList.add(3);
intList.add(4);


    Integer[] array = intList.stream()
                             .filter(x -> x > 2)
                             .toArray(x -> {
                                System.out.println("x --> " + x);
                                return new Integer[x];
                              });

System.out.println("array length: " + array.length);
Run Code Online (Sandbox Code Playgroud)

上述代码的输出:

x --> 2
array length: 2
Run Code Online (Sandbox Code Playgroud)

最初,片段就像

Integer[] array = intList.stream()
                 .filter(x -> x > 2)
                 .toArray(x -> new Integer[x]);
Run Code Online (Sandbox Code Playgroud)

只是为了理解它传递的x的值,我必须改变它以在lambda中打印x

Hol*_*ger 5

当然,这取决于实现.对于某些流,如果源具有已知大小并且不涉及大小改变中间操作,则大小是可预测的.由于您使用的是filter操作,因此不适用,但是,根据未过滤的计数,存在估计大小.

现在,Stream实现只是使用估计的大小或默认大小来分配临时缓冲区,如果需要,可以支持增加容量,并在最后一步将数据复制到由函数创建的目标数组中.

中间缓冲区可以通过提供的函数创建,这就是文档说明"... 使用提供的生成器函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组 "的原因.我依稀记得在早期版本中看到过这样的行为.但是,当前实现仅使用Object[]数组(或Object[][]"spined缓冲区"中)进行中间存储,并仅使用提供的函数来创建最终数组.因此,在给定此特定JRE实现的情况下,您无法使用该函数观察中间数组的创建.


Gho*_*ica 4

问题是:这是一个终端操作。它发生在最后,当流被处理时:意思是-“最终”计数到那时就已知了;因为没有更多的操作可以删除/添加值到流中!

  • @Loks 它创建一个包含所有引用的集合,然后它知道长度并调用此 lambda。 (3认同)