Die Antwort lautet wie immer "es kommt darauf an". Dies hängt davon ab, wie groß die zurückgegebene Sammlung sein wird. Dies hängt davon ab, ob sich das Ergebnis im Laufe der Zeit ändert und wie wichtig die Konsistenz des zurückgegebenen Ergebnisses ist. Und es hängt sehr davon ab, wie der Benutzer die Antwort wahrscheinlich verwendet.
Beachten Sie zunächst, dass Sie immer eine Sammlung aus einem Stream abrufen können und umgekehrt:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
Die Frage ist also, was für Ihre Anrufer nützlicher ist.
Wenn Ihr Ergebnis unendlich sein könnte, gibt es nur eine Wahl: Stream.
Wenn Ihr Ergebnis sehr groß sein könnte, bevorzugen Sie wahrscheinlich Stream, da es möglicherweise keinen Wert hat, alles auf einmal zu materialisieren, und dies könnte einen erheblichen Heap-Druck erzeugen.
Wenn der Aufrufer nur iterieren möchte (suchen, filtern, aggregieren), sollten Sie Stream bevorzugen, da Stream diese bereits integriert hat und keine Sammlung materialisiert werden muss (insbesondere, wenn der Benutzer die Sammlung möglicherweise nicht verarbeitet) ganzes Ergebnis.) Dies ist ein sehr häufiger Fall.
Selbst wenn Sie wissen, dass der Benutzer es mehrmals iterieren oder auf andere Weise beibehalten wird, möchten Sie möglicherweise stattdessen einen Stream zurückgeben, da die Sammlung, in die Sie ihn einfügen (z. B. ArrayList), möglicherweise nicht die ist Formular, das sie wollen, und dann muss der Anrufer es trotzdem kopieren. Wenn Sie einen Stream zurückgeben, können collect(toCollection(factory))
sie ihn in genau der gewünschten Form abrufen.
Die oben genannten Fälle "Stream bevorzugen" ergeben sich hauptsächlich aus der Tatsache, dass Stream flexibler ist. Sie können sich spät daran binden, wie Sie es verwenden, ohne die Kosten und Einschränkungen für die Materialisierung in einer Sammlung zu verursachen.
Der einzige Fall, in dem Sie eine Sammlung zurückgeben müssen, besteht darin, dass hohe Konsistenzanforderungen bestehen und Sie einen konsistenten Schnappschuss eines sich bewegenden Ziels erstellen müssen. Dann möchten Sie die Elemente in eine Sammlung einfügen, die sich nicht ändert.
Daher würde ich sagen, dass Stream die meiste Zeit die richtige Antwort ist - es ist flexibler, verursacht normalerweise keine unnötigen Materialisierungskosten und kann bei Bedarf problemlos in die Sammlung Ihrer Wahl umgewandelt werden. Manchmal müssen Sie jedoch eine Sammlung zurückgeben (z. B. aufgrund starker Konsistenzanforderungen), oder Sie möchten die Sammlung zurückgeben, weil Sie wissen, wie der Benutzer sie verwenden wird, und wissen, dass dies für ihn am bequemsten ist.
players.stream()
ist genau eine solche Methode, die einen Stream an den Aufrufer zurückgibt. Die eigentliche Frage ist, möchten Sie den Anrufer wirklich auf eine einzelne Durchquerung beschränken und ihm auch den Zugriff auf Ihre Sammlung über dieCollection
API verweigern ? Vielleicht möchte der Anrufer es einfach zuaddAll
einer anderen Sammlung?