[解決済み] コレクションとストリームのどちらを返すべきですか?
質問
メンバーリストへの読み取り専用ビューを返すメソッドがあるとします。
class Team {
private List<Player> players = new ArrayList<>();
// ...
public List<Player> getPlayers() {
return Collections.unmodifiableList(players);
}
}
さらに、クライアントが行うのは、リストに対して一度、即座に反復処理を行うだけだとします。たとえば、プレーヤーを JList か何かに入れるためです。クライアントが行うのは ない は、後で見るためにリストへの参照を保存します。
このよくあるシナリオを考えると、代わりにストリームを返すべきでしょうか?
public Stream<Player> getPlayers() {
return players.stream();
}
それとも、Javaではストリームを返すことは非日常的なことなのでしょうか?ストリームは常に、作成されたのと同じ式の内部で "terminate"されるように設計されていたのでしょうか?
解決方法は?
答えは、いつものように、quot;it depends"です。 返されるコレクションがどれくらいの大きさになるかによります。 結果が時間とともに変化するかどうか、また、返される結果の一貫性がどれほど重要であるかによります。 そして、ユーザーがその答えをどのように使用するかに大きく依存します。
まず、注意点として、常に
Collection
から
Stream
また、その逆も同様です。
// 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
はすでにこれらを内蔵しており、コレクションを実体化する必要はありません (特に、ユーザーが結果全体を処理しない可能性がある場合)。 これは非常によくあるケースです。
ユーザーが何度も反復したり、そうでなくともそれを維持することが分かっていても、やはり
Stream
その理由は、どのような
Collection
を選択し、それを入れる(例.
ArrayList
) が、彼らの望む形でない可能性があり、その場合、呼び出し側はとにかくそれをコピーしなければならない。 もしあなたが
Stream
を行うことができます。
collect(toCollection(factory))
を、思い通りの形で手に入れることができます。
上記の "preferは
Stream
という事実からきています。
Stream
の方がより柔軟性があります。
Collection
.
を返さなければならないケースは
Collection
は、強い一貫性の要求があり、移動するターゲットの一貫したスナップショットを作成する必要がある場合です。 その場合、要素を変更されないようにコレクションに格納する必要があります。
だから、たいていの場合はそうだと言えるでしょう。
Stream
より柔軟性があり、通常不要なマテリアライゼーション・コストがかからず、必要に応じて簡単に好きなコレクションに変更することができます。 しかし、時には
Collection
(例えば、強い一貫性要求のため)、あるいは
Collection
というのも、ユーザーがどのように使うか知っていて、これが一番便利だとわかっているからです。
すでに適切な
Collection
として扱うほうがよさそうです。
Collection
であれば、今あるものをそのまま返すというのは合理的な選択です(ただし、唯一の選択ではなく、よりもろいものです)。
関連
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] コレクションを反復処理し、ループ内でオブジェクトを削除する際に ConcurrentModificationException を回避する。
-
[解決済み] Java 8 StreamをArrayに変換する方法は?
-
[解決済み] Javaコレクションをフィルタリングする方法(述語に基づく)?
-
[解決済み] 可能な限り常にパラレルストリームを使用した方がいいのでしょうか?
-
[解決済み] IteratorをStreamに変換するには?
-
[解決済み] Java 8 JDK を使用して、Iterable を Stream に変換する
-
[解決済み] Java 8でインデックスを持つストリームを反復処理する簡潔な方法はありますか?
-
[解決済み] Java 8 の並列ストリームにおけるカスタムスレッドプール
-
[解決済み】nullと空のコレクションのどちらを返すのが良いですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
java の例外が発生しました java
-
プロジェクトの依存関係を解決できなかった 解決
-
サーブレットクラスのインスタンス化エラーの解決法
-
VMの初期化中にエラーが発生しました java/lang/NoClassDefFoundError: java/lang/Object
-
Spring BootのテストメソッドFailed to load ApplicationContextの問題を解決する
-
自動配線された依存性のインジェクションに失敗しました。
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
あるコードに出会いましたが、何に使うのか理解できません。 List<String> list = new ArrayList<String>() { { a
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について