La respuesta es, como siempre, "depende". Depende de qué tan grande será la colección devuelta. Depende de si el resultado cambia con el tiempo y de cuán importante es la consistencia del resultado devuelto. Y depende mucho de cómo es probable que el usuario use la respuesta.
Primero, tenga en cuenta que siempre puede obtener una Colección de un Stream, y viceversa:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
Entonces la pregunta es, ¿cuál es más útil para las personas que llaman?
Si su resultado puede ser infinito, solo hay una opción: Stream.
Si su resultado puede ser muy grande, probablemente prefiera Stream, ya que puede que no tenga ningún valor materializarlo todo de una vez, y hacerlo podría generar una gran presión de almacenamiento dinámico.
Si todo lo que va a hacer la persona que llama es iterar a través de él (buscar, filtrar, agregar), debe preferir Stream, ya que Stream ya tiene estos incorporados y no hay necesidad de materializar una colección (especialmente si el usuario no puede procesar el Stream resultado completo.) Este es un caso muy común.
Incluso si sabe que el usuario lo repetirá varias veces o lo mantendrá, puede que desee devolver un Stream en su lugar, por el simple hecho de que cualquier Colección que elija para colocarla (por ejemplo, ArrayList) puede no ser la la forma que desean, y la persona que llama tiene que copiarla de todos modos. si devuelve una transmisión, pueden hacerlo collect(toCollection(factory))
y obtenerla exactamente de la forma que deseen.
Los casos anteriores de "preferir Stream" se derivan principalmente del hecho de que Stream es más flexible; puede vincularse tarde a cómo lo usa sin incurrir en los costos y las limitaciones de materializarlo en una Colección.
El único caso en el que debe devolver una Colección es cuando existen requisitos de consistencia sólidos y tiene que producir una instantánea consistente de un objetivo en movimiento. Entonces, querrás poner los elementos en una colección que no cambiará.
Entonces, diría que la mayoría de las veces, Stream es la respuesta correcta: es más flexible, no impone costos de materialización usualmente innecesarios y puede convertirse fácilmente en la Colección de su elección si es necesario. Pero a veces, puede que tenga que devolver una Colección (por ejemplo, debido a los requisitos de coherencia), o puede que desee devolver la Colección porque sabe cómo la usará el usuario y sabe que esto es lo más conveniente para ellos.
players.stream()
es un método que devuelve una secuencia a la persona que llama. La verdadera pregunta es, ¿realmente desea restringir al llamante a un recorrido único y también negarle el acceso a su colección a través de laCollection
API? ¿Quizás la persona que llama solo quiere iraddAll
a otra colección?