2016-04-01 9 views
2

Ich versuche, Java-8-Streams im Detail zu verstehen.Java-8-Streams: Werden neue Streams von Zwischenoperationen ohne Speichererweiterung zurückgegeben?

von Oracle-Dokumentation Seite auf streams:

Streams unterscheiden sich von Sammlungen in mehrfacher Hinsicht:

Keine Lagerung. Ein Stream ist keine Datenstruktur, die Elemente speichert. Stattdessen überträgt es Elemente aus einer Quelle wie einer Datenstruktur, einem Array, einer Generatorfunktion oder einem E/A-Kanal durch eine Pipeline von Rechenoperationen.

Stream-Operationen und Pipelines

Stream-Operationen werden in Zwischen- und Operationen unterteilt und werden kombiniert Stream-Pipeline zu bilden.

Eine Stream-Pipeline besteht aus einer Quelle (z. B. einer Sammlung, einem Array, einer Generatorfunktion oder einem E/A-Kanal). gefolgt von null oder mehr Zwischenoperationen wie Stream.filter oder Stream.map; und eine Terminaloperation wie Stream.forEach oder Stream.reduce.

How does streams in Java affect memory consumption?

wurde Überall dort, wo zusätzliche Speicher zitiert nicht war:

Zwischenoperationen geben einen neuen Stream

Neben Dokumentation habe ich über verbundene SE Frage gegangen verbraucht aufgrund der Rohrauskleidung von Stream-Operationen. Der ursprüngliche Stream wird durch eine Pipeline geleitet.

Ein funktionierendes Beispiel aus Benjamin Blog:

List<String> myList = 
    Arrays.asList("a1", "a2", "b1", "c2", "c1"); 

myList 
    .stream() 
    .filter(s -> s.startsWith("c")) 
    .map(String::toUpperCase) 
    .sorted() 
    .forEach(System.out::println); 

Aber als Zwischenoperationen wie filter, map and sorted neuen Strom zurückkehrt, wie kommt es nicht den Speicherverbrauch nicht erhöht? Fehle ich hier etwas?

+3

Die Objekte erstellt haben ein kurzes Leben, der Müllsammler ist sehr gut zu fegen sie. – Tunaki

+1

Um alle Elemente zu sortieren, müssen sie gespeichert werden, da Sie nicht wissen, dass Sie das kleinste Element haben, bis Sie alle gesehen haben. –

Antwort

1

Versuchen Sie hier zu lesen http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html und/oder hier http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/, die Konzepte, die Sie versuchen, herauszufinden, ist ziemlich gut erklärt, denke ich.

Grundsätzlich können Sie sehen, dass es für die meisten Zwischenoperationen nicht für jeden Vorgang gleichzeitig geschieht. Jeweils ein Element wird durch alle Zwischenoperationen verarbeitet und entweder verworfen oder in Abhängigkeit von der Terminaloperation in eine Sammlung/addiert zu einer Summe/gedruckt usw. gelegt. Wenn es sich um eine Terminal-Operation vom Collect-Typ handelt, wird natürlich bei der Erstellung dieser neuen Sammlung etwas Speicheraufwand anfallen, aber einzeln im Stream wird nichts gespeichert. Dies ist auch der Grund, warum Sie nicht zweimal (teilweise) über einen Stream iterieren können.

Es gibt jedoch einige Operationen, z. B. stream.sorted (func), die möglicherweise während der Verarbeitung einen Status benötigen.

+0

Also im Grunde würde es Spike im RAM geben und es wird nach Garbage Collection schnell untergehen. Habe ich recht? –

+0

Es gibt keine Stream-Operation, die die zugrunde liegende anfängliche Sammlung ändert. Das ist das Designprinzip. Daher kann (und sollte) die Formulierung "es sei denn, sie ändern einfach die zugrundeliegende ursprüngliche Sammlung" entfernt werden. – Holger

+0

Ja, natürlich hast du recht Holger, dachte ich, ich hätte das irgendwo gesehen. Hätte das zuerst überprüfen sollen, tut mir leid. – PNS

7

Ich denke, Sie interpretiert "keinen Speicher" Abschnitt der Dokumentation zu wörtlich, wie "keine Speichererhöhung." Diese Interpretation ist falsch: "kein Speicher" bedeutet "kein Speicher für Stream-Elemente". Das Stream-Objekt selbst stellt einen festen Overhead dar, genau wie eine leere Sammlung einen gewissen Overhead hat, so dass die Größe des Streams selbst nicht zählt.

Aber wenn Zwischenoperationen wie Filter, Map und Sorted einen neuen Stream zurückgeben, wie kommt es dann, dass es den Speicherverbrauch nicht erhöht?

Es tut. Die Zunahme der Grße ist jedoch fest, d. H. Eine Zunahme von O (1). Dies steht im Gegensatz zu Sammlungen, wo der Anstieg für das Erstellen einer Kopie einer Sammlung von n Elementen O (n) ist.

Verwandte Themen