我希望以前没有问过这个问题。
在java 8中,我在输入中有一个String myArray
数组和一个整数maxLength
。
我想计算我的数组中的字符串数小于maxLength。我想使用流来解决这个问题。
为此,我想这样做:
int solution = Arrays.stream(myArray).filter(s -> s.length() <= maxLength).count();
但是,我不确定这是否是正确的方法。它需要经过第一个数组,然后通过过滤后的数组进行计数。
但如果我不使用流,我可以轻松地制作一个算法,在myArray上循环一次。
我的问题非常简单:有没有办法以相同的时间性能解决此问题而不是循环?它总是一个好的&#34;使用流的解决方案?
答案 0 :(得分:6)
但是我不确定这是否是正确的方法。它需要 通过第一个数组,然后通过过滤后的数组 数数。
您认为它将执行多次传递是错误的。有一些叫操作融合的东西,即可以在数据的单次传递中执行多个操作;
在这种情况下Arrays.stream(myArray)
将创建一个流对象(廉价操作和轻量级对象),filter(s -> s.length() <= maxLength).count();
将合并为一个数据传递,因为在管道中没有有状态操作过滤流的所有元素,然后计算传递谓词的所有元素。
Brian Goetz post here的一句话引用:
相比之下,流管道将其运营融合为少数 尽可能传递数据,通常只传递一次。 (有状态 中间操作,例如排序,可以引入障碍点 这需要多次执行。)
至于:
我的问题很简单:有没有办法解决这个问题 同时表现比一个循环?
取决于数据量和每个元素的成本。无论如何,对于少数元素,循环的必要性几乎总是赢得,如果不是总是。
使用流总是一个“好”的解决方案吗?
不,如果您真的关心性能,那么衡量,衡量和衡量。
使用流来表示它是声明性的,因为它的抽象,组合以及从并行性中受益的可能性,当你知道你将从中受益时。
答案 1 :(得分:0)
您可以使用range
代替stream
并过滤输出。
int solution = IntStream.range(0, myArray.length)
.filter(index -> myArray[index].length() <= maxLength)
.count();