2016-04-01 9 views
2

私はjava-8ストリームを詳細に理解しようとしています。 streams上のOracleのドキュメントページからjava-8ストリーム:中間操作の新しいストリームはメモリの増加なしに返されますか?

ストリームは、いくつかの方法でのコレクションとは異なります。

ないストレージ。ストリームは、要素を格納するデータ構造ではありません。代わりに、データ構造、配列、ジェネレータ関数、またはI/Oチャネルなどのソースから計算操作のパイプラインを通じて要素を伝達します。

ストリーム操作とパイプライン

ストリーム操作は、中間および端末操作に分割され、ストリームパイプラインを形成するために結合されます。

ストリームパイプラインは、ソース(コレクション、配列、ジェネレータ関数、またはI/Oチャネルなど)で構成されます。続いてStream.filterやStream.mapのようなゼロ以上の中間的な操作が続きます。 Stream.forEachやStream.reduceのような端末操作が含まれます。

中級操作が

は別にドキュメントから、私は関連のSEの質問を経てきた新しいストリームを返す:どこ

How does streams in Java affect memory consumption?

それは、追加のメモリがなかったことを引用しました。ストリーム操作のパイプライニングのために消費されます。元のストリームはパイプラインを通過します。

Benjaminブログから一つの作業例:

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); 

しかしfilter, map and sortedのような中間の操作が新しいストリームを返すとき、どのように来ることは、メモリの消費量を増加させませんか?私はここに何かを逃していますか

+3

作成されたオブジェクトの寿命が短く、ガベージコレクタが非常に優れています。 – Tunaki

+1

すべての要素を並べ替えるには、その要素をすべて格納しておく必要があります。 –

答えて

1

http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.htmlおよび/またはここにhttp://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/を読もうとすると、あなたが把握しようとしているコンセプトはかなりよくわかっていると思います。

基本的には、ほとんどの中間操作では、操作ごとに一気に実行されるわけではありません。 1要素を一度にすべての中間演算によって処理し、終端演算に応じて破棄するか、コレクションに入れるか、合計/印刷したものに加えるかのいずれかである。それが収集タイプのターミナル操作であれば、この新しいコレクションを作成するときにメモリオーバーヘッドが発生することはもちろんありますが、ストリームには何も保存されません。これはまた、ストリームを2回(部分的に)繰り返すことができない理由です。

ただし、処理中に何らかの状態が必要なstream.sorted(func)などの操作があります。

+0

基本的にはRAMにスパイクがあり、ガベージコレクションの後すぐにダウンします。私は正しい? –

+0

基礎となる初期コレクションを変更するストリーム操作はありません。それがデザインの原則です。したがって、「基本的な初期コレクションを単純に変更しない限り、」というフレーズは削除できます(削除する必要があります)。 – Holger

+0

もちろん、あなたは正しいホルガーです、私はどこかでそれを見たと思っていました。それを最初にチェックしておかなければならない。 – PNS

7

「メモリが増えない」と言って、ドキュメントの「ストレージなし」の部分も文字通りに解釈したと思います。この解釈は正しくありません。「ストレージがない」とは、「ストリーム要素のストレージがありません」という意味です。ストリームオブジェクト自体は固定オーバーヘッドを表します。空のコレクションにはオーバーヘッドがあるのと同じ方法で、ストリーム自体のサイズはカウントされません。

しかし、フィルタ、マップ、ソートなどの中間処理で新しいストリームが返されると、どのようにメモリ消費量が増加しないのでしょうか?

です。しかしながら、サイズの増加は固定されており、すなわちO(1)が増加している。これは、n要素のコレクションのコピーを作成するための増加がO(n)であるコレクションとは対照的です。

関連する問題