【发布时间】:2015-11-13 03:19:11
【问题描述】:
我正在试验 Java 的 Streams,并试图找出可能的方法以及它们的优缺点。目前我正在尝试使用流来实现 Eratosthenes 筛,但似乎找不到一种好方法来循环遍历先前过滤的值而不将它们存储在单独的集合中。
我想要完成这样的事情:
IntStream myStream = IntStream.range(0,3);
myStream.filter(s -> {
System.out.print("[filtering "+s+"] ");
myStream.forEach(q -> System.out.print(q+", "));
System.out.println();
return true; //eventually respond to values observed on the line above
});
期望输出:
[filtering 0]
[filtering 1] 0,
[filtering 2] 0, 1,
[filtering 3] 0, 1, 2,
请注意,在过滤每个新值时,会观察所有先前过滤的值。这样可以轻松实现埃拉托色尼筛法,因为我可以过滤掉所有非质数,并为每个新值检查与之前通过质数过滤器的所有数字的可分性。
但是,上面的示例在 NetBeans 中给我一个错误:
local variables referenced from a lambda expression must be final or effectively final
这似乎是因为我在已经作用于 myStream 的过滤器中引用了 myStream。是否有解决此错误的好方法(即制作仅包含到目前为止已过滤的值的流的最终副本),或者是否有更好的方法来解决此类问题而不使用单独的集合来存储价值观?
【问题讨论】:
-
不,没有比使用单独的集合更好的方法了。 Stream API 不是为这种用途而设计的。
-
使用现有的代码,您可以将
final关键字放在IntStream myStream之前。但是代码无论如何都不正确,因为您需要将第二行更改为myStream = myStream.filter(...),否则您将使用未经过滤的流。
标签: java filter lambda java-8 java-stream