2016-10-19 9 views
3

ストリーム:副作用私は完全には理解できないのOracleドキュメントのいくつかのものがあります

Operations like forEach and peek are designed for side effects; 

彼らは「設計された」の意味は何?これらの2つについては何が特別ですか?私は任意のストリームAPIメソッドが副作用を介して動作するように自分のコードを書くことができます。私が理解できる限り、それは完全に私のものです。さらに、私は通常、ソース自体ではなく要素の状態を変更するためにpeek()を使用しますが、ステートフルまたは副作用の原因にはなりません。

のforEachのjavadocも書かれています:

The behavior of this operation is explicitly nondeterministic. 

彼らはfindAnyについて同じことを言うとき、私はそれを理解しますが、何がforEachのおよそ非決定ですか?パラレル・ストリームでの操作は、ストリームが順序付けられていない場合は順序付けを保証できません。非決定論はなぜforEach(とfinAny、しかしそれはちょっと別のことを意味する)について言及されていますか? PEEKとのforeachのjavadocについては

も含まれています

action may be performed at whatever time and in whatever thread the library chooses 

ここでも、なぜそこだけ?それは残りの操作についてはなぜ言及されていないのですか?

+3

まあ、あなたの質問の2つのポイントは実際にそれに答える。通常の中間作業では、副作用や干渉のないものでなければならないため、非決定性は無関係です。 'forEach'では、"副作用のために設計されている "ため、非決定性は重要であり、文書化されなければなりません。 – Holger

+3

正解を求めているのはあなた次第です。この仕様では、ほとんどのストリームメソッドに渡されるビヘイビアパラメータが_stateless_であることを明確に述べています。つまり、計算に影響する可能性のある副作用がある場合、正しい答えを得る保証はありません。 –

+0

したがって、「副作用のために設計された」とは、実際には、副作用に対して弾力性を持たせるために、peekとforEachの実装に何かがあることを意味しますが、残りの機能は同じことを保証できません。 – yuranos87

答えて

5

まず、ラムダを実行した後にプログラムの全体的な状態が変化するため、オブジェクトの状態を変更することも副作用です。並列ストリームで同じオブジェクトを複数回使用すると、ここで並行性の問題が発生する可能性があります。副作用のない関数は、プログラムの状態を変更しない関数であり、その戻り値はその引数のみに基づいています。他のストリーム操作には副作用がないことが要求されるので、どのスレッドで実行するかは問題ではないので、どのスレッドで実行するかは言及する必要はありません。しかし、操作が副作用を許される場合、これは明示的に言及されるべきである。

forEachは、ストリームが順序付けられていない場合でも、forEachOrdered異なりますforEachOrderedは常にそのラムダは、一度に複数の異なるスレッドで同時に実行されていないことを保証します。 forEachコールは、あなたのストリームを暗黙的に並べ替えないだけでなく、この保証を取り除きます。ラムダは今すぐ同時に実行できます。ラムダは副作用を引き起こすかもしれないので、これは明示的に言及するべきです。

関連する問題