我從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等。無論如何,我想這應該採取元... –