我从java 8 API流上的抽象,但 读书,我不明白这句话非常好:流和懒惰评估
中级操作返回一个新的流。他们总是懒惰;执行诸如filter()之类的中间操作实际上并不执行任何过滤,而是创建一个新流,当 遍历时,它包含初始流的元素,该初始流的元素与给定的谓词相匹配 。直到 管道的终端操作被执行,流水线源的遍历才开始。
当过滤器操作创建新的流时,该流是否包含过滤的元素? 似乎了解,流只包含遍历的元素,即使用终端操作。但是,比什么包含过滤的流?我很困惑!!!
我从java 8 API流上的抽象,但 读书,我不明白这句话非常好:流和懒惰评估
中级操作返回一个新的流。他们总是懒惰;执行诸如filter()之类的中间操作实际上并不执行任何过滤,而是创建一个新流,当 遍历时,它包含初始流的元素,该初始流的元素与给定的谓词相匹配 。直到 管道的终端操作被执行,流水线源的遍历才开始。
当过滤器操作创建新的流时,该流是否包含过滤的元素? 似乎了解,流只包含遍历的元素,即使用终端操作。但是,比什么包含过滤的流?我很困惑!!!
这意味着过滤器仅在终端操作期间应用。想想这样的事情:
public Stream filter(Predicate p) {
this.filter = p; // just store it, don't apply it yet
return this; // in reality: return a new stream
}
public List collect() {
for (Object o : stream) {
if (filter.test(o)) list.add(o);
}
return list;
}
(无法编译,是现实的简化,但原则是存在的)
流是懒惰的,因为除非是调用终端操作中间业务不被评估。
每个中间操作创建一个新的流,存储提供的操作/函数并返回新的流。
流水线累积了这些新创建的流。
调用终端操作的时间,流的遍历开始并且相关的函数逐个执行。
并行流不会逐个评估流(在终点)。这些操作是同时执行的,取决于可用的内核。
在我看来,这中间操作中不完全懒:
List<String> l3 = new ArrayList<String>();
l3.add("first");
l3.add("second");
l3.add("third");
l3.add("fouth");
l3.add("fith");
l3.add("sixth");
List<String> test3 = new ArrayList<String>();
try {
l3.stream().filter(s -> { l3.clear(); test3.add(s); return true;}).forEach(System.out::println);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("!!! ");
System.out.println(test3.stream().reduce((s1, s2) -> s1 += " ;" + s2).get());
}
Otput:
first
null
null
null
null
null
java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at test.TestParallel.main(TestParallel.java:69)
!!!
first ;null ;null ;null ;null ;null
貌似对流创建迭代套数,但歌厅一个新的流元素懒惰。
你可以请格式化您的代码,突出显示它,并按Ctrl + K – WhatsThePoint
@Lukas,我们已经为Java 8 Stream API提供了[tag:java-stream]。您创建的标签非常...通用。 – Charles
但它的正式名称是“Streams API”,而不是“Java-Stream”。 Java Stream可以表示任何东西。包括InputStream/OutputStream等。无论如何,我想这应该采取元... –