我对Java8StreamAPI并不熟悉,实际上我不明白为什么我的代码不能工作:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Stream.iterate(0, x -> x+3)
.filter(x -> x>10 && x<100).peek(System.out::println)
.collect(Collectors.toList());
numbers.forEach(System.out::println);
}
}当我理解溪流的“懒惰”时,我写道:
正如我所看到的,无穷大循环有一些问题,所以peek()从范围(12,99)打印数字是可以的,但是在那之后,它再次打印来自(11,98)的数字等等。你能解释我在哪里出错了吗?
发布于 2014-08-06 18:00:13
编译器和运行时都不知道filter会过滤掉100以上的所有数字。因此,运行库继续生成无限个整数,并将筛选器应用于它们。
您有多种解决此问题的方法:
使用limit将无限流截断为有限流。这使得下面的过滤器有点不必要(如果您设置了一个严格的限制,那么只有x>10测试仍然相关)。
public static void main(String[] args) {
List<Integer> numbers = Stream.iterate(0, x -> x+3)
.limit(34)
.filter(x -> x>10 && x<100).peek(System.out::println)
.collect(Collectors.toList());
numbers.forEach(System.out::println);
}使用IntStream.range并乘以3:
public static void main(String[] args) {
List<Integer> numbers = IntStream.range(0, 34)
.map(x -> 3*x)
.collect(Collectors.toList());
numbers.forEach(System.out::println);
}一般来说,流的“懒惰”意味着它们只有在遇到终端(最终)操作时才开始执行。如果操作需要处理列表中的所有元素(如toList ),则不应将其传递为无限流。
当您处理无限流时,您的选项是将其截断为有限流(使用限制),或者有一个不需要处理流的所有元素的终端操作(例如: anyMatch、findFirst、findAny)。
https://stackoverflow.com/questions/25167000
复制相似问题