答えは、いつものように、「それは依存する」です。返されるコレクションの大きさによって異なります。結果が時間とともに変化するかどうか、および返される結果の一貫性がどの程度重要であるかによって異なります。そして、それはユーザーが答えをどのように使用する可能性が高いかに大きく依存します。
まず、いつでもストリームからコレクションを取得でき、その逆も可能です。
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
質問は、発信者にとってより便利です。
結果が無限になる可能性がある場合、選択肢はストリームのみです。
結果が非常に大きい場合は、Streamを使用することをお勧めします。これは、一度に実体化することに価値がなく、そうすることで大きなヒープ圧力が発生する可能性があるためです。
呼び出し元がすべて繰り返す(検索、フィルター、集計)場合は、Streamを優先する必要があります。これは、Streamに既にこれらが組み込まれており、コレクションを具体化する必要がないためです(特に、ユーザーが処理しない場合)。結果全体)。これは非常に一般的なケースです。
ユーザーが複数回繰り返したり、別の方法で繰り返したりすることがわかっている場合でも、代わりにStreamを返すことをお勧めします。これは、配置するように選択したコレクション(たとえば、ArrayList)が彼らが望むフォーム、そして呼び出し側はとにかくそれをコピーする必要があります。ストリームを返す場合、ストリームを実行collect(toCollection(factory))
して、希望どおりの形式で取得できます。
上記の「Streamを優先する」ケースは、ほとんどの場合、Streamの方が柔軟性があるという事実から派生しています。コレクションへの具体化のコストや制約を負うことなく、それを使用方法に後からバインドできます。
コレクションを返す必要があるのは、強い整合性要件があり、移動するターゲットの整合性のあるスナップショットを作成する必要がある場合です。次に、要素を変更されないコレクションに配置します。
したがって、ほとんどの場合、Streamが正解です。より柔軟であり、通常は不要な具体化コストを課すことはなく、必要に応じて選択したコレクションに簡単に変換できます。しかし、場合によっては、コレクションを返す必要があります(たとえば、強い整合性の要件のため)、またはユーザーがコレクションを使用する方法を知っていて、これがユーザーにとって最も便利であることを知っているので、コレクションを返したい場合があります。
players.stream()
呼び出し元にストリームを返すようなメソッドです。本当の問題は、呼び出し元を単一のトラバーサルに制限し、Collection
APIを介してコレクションへのアクセスを拒否したいですか?たぶん、発信者はaddAll
別のコレクションにそれを望んでいるか?