Java 8流的toArray和size参数

时间:2017-02-16 10:07:24

标签: 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);

输出上述代码:

x --> 2
array length: 2

最初,该片段就像

Integer[] array = intList.stream()
                 .filter(x -> x > 2)
                 .toArray(x -> new Integer[x]);

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

3 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:3)

问题是:这是 terminal 操作。它最终发生在流处理时:意思是 - &#34; final&#34;算是知道的;因为没有更多的操作可以删除/添加流的值!

答案 2 :(得分:3)

只需查看toArray的javas stream文档即可。

<A> A[] toArray(IntFunction<A[]> generator)

返回一个包含此流元素的数组,使用提供的生成器函数分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。

这是终端操作。

API注意:     生成器函数采用一个整数,它是所需数组的大小,并生成一个所需大小的数组。这可以用数组构造函数引用简洁地表示

因此,toArray确实为您提供了所需的数组大小作为参数,并且您负责分配正确大小的数组,至少在使用此方法时。该方法是终端操作。因此,大小计算是在Stream API的内部完成的。

恕我直言,最好掌握你是否为filter和toArray命名不同的lambda参数。

Integer[] array = intList.stream()
                 .filter(myint -> myint > 2)
                 .toArray(desiredArraySize -> new Integer[desiredArraySize]);