尽管我们有过滤器,为什么此流不会停止打印1
?
有人可以向我解释一下吗?这个例子不准确,是操作流的最佳例子,它仅用于学习目的。
Stream.generate(() -> "1")
.peek(System.out::println)
.filter(x -> x.length() > 1)
.limit(10)
.forEach(System.out::println);
正确的是:
Stream.generate(() -> "1")
.limit(10)
.forEach(System.out::println);
答案 0 :(得分:4)
将流视为管道。元素将继续从generate
方法中出现。然后,每个元素都会通过每个后续操作。
所以在你的代码中:
Stream.generate(() -> "1")
.peek(System.out::println)
.filter(x -> x.length() > 1)
.limit(10)
.forEach(System.out::println);
以下内容继续:
"1"
peek
,您的"1"
已打印filter
,如果"1"
的长度大于1,它将会通过,否则会被丢弃"1"
通过过滤器,则会达到限制。限制只允许前10个元素通过。在第10个元素之后,它将抛出元素没有元素会通过过滤器,因为"1"
的长度永远不会大于1. limit
永远不会让足够的元素通过,因此终端操作没有到达,它永远不会终止。
这就是为什么它继续重复前两行。
我现在解释为什么要颠倒limit
和filter
的顺序:
Stream.generate(() -> "1")
.peek(System.out::println)
.limit(10)
.filter(x -> x.length() > 1)
.forEach(System.out::println);
peek
首先打印10个元素,然后通过limit
位。然后,所有这10个元素都没有通过filter
。但是这一次,终端操作已经到达,因为filter
不像limit
,它在继续之前等待10个元素。整个事情终止,不再生成任何元素。
答案 1 :(得分:1)
从文档中,方法generate
返回一个无限序列,要求它执行:
static <T> Stream<T> generate(Supplier<T> s)
返回无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
所以Stream.generate(() -> "1").peek(System.out::println)
永不停止
你也会这样,但由于filter
.filter(x -> x.length() > 1)
.limit(10)
.forEach(System.out::println);
打印1
十次:
Stream.generate(() -> "1").limit(10).forEach(System.out::println);
// OR
IntStream.generate(() -> 1).limit(10).forEach(System.out::println);
答案 2 :(得分:1)
你真的期待什么?
Stream.generate(() -> "1") // generates a String of length one
.peek(System.out::println) // prints it
.filter(x -> x.length() > 1) // filters those that have length bigger than one
.limit(10) // this is NEVER reached
.forEach(System.out::println); // this is NEVER reached
由于终端操作永远不会被命中,因此流不断地生成元素。
另一方面,第二个例子不受此影响,没有filter
和限制 - 在10个元素达到其界限后。
答案 3 :(得分:-1)
在过滤之前先看一眼,这就是打印前过滤器不适用的原因。