Відповідь, як завжди, "це залежить". Це залежить від того, наскільки велика буде повернена колекція. Це залежить від того, чи змінюється результат з часом, і наскільки важливою є послідовність повернутого результату. І це дуже залежить від того, як користувач може скористатися відповіддю.
По-перше, зауважте, що Ви завжди можете отримати колекцію з потоку, і навпаки:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
Тож питання в тому, що корисніше вашим абонентам.
Якщо ваш результат може бути нескінченним, є лише один вибір: Потік.
Якщо ваш результат може бути дуже великим, ви, мабуть, віддаєте перевагу Потоку, оскільки може бути нецілком важливо в матеріалізації цього за один раз, і це може призвести до значного тиску в купі.
Якщо все, що викликає абонент, буде переглядати його (шукати, фільтрувати, агрегатувати), вам слід віддати перевагу потоку, оскільки Stream вже має вбудовані і не потрібно матеріалізувати колекцію (особливо якщо користувач може не обробляти весь результат.) Це дуже поширений випадок.
Навіть якщо ви знаєте, що користувач буде повторювати його кілька разів або іншим чином тримати його навколо, ви все одно можете захотіти повернути Потік замість цього простого факту, що в будь-яку колекцію, яку ви вирішите помістити, (наприклад, ArrayList), можливо, це не буде форму, яку вони хочуть, і тоді абонент повинен все-таки скопіювати її. якщо ви повернете потік, вони можуть це зробити collect(toCollection(factory))
і отримати їх у потрібній формі.
Вищенаведені випадки "віддають перевагу потоку" здебільшого випливають із того, що потік є більш гнучким; ви можете пізно прив’язатись до того, як ви ним користуєтесь, не покладаючи на себе витрат і обмежень матеріалізації для колекції.
Єдиний випадок, коли ви повинні повернути колекцію, - коли є чіткі вимоги послідовності, і ви повинні створити послідовний знімок рухомої цілі. Потім ви захочете помістити елементи в колекцію, яка не зміниться.
Тому я б сказав, що більшість часу Stream - це правильна відповідь - вона більш гнучка, вона не покладає зазвичай-зайвих витрат на матеріалізацію, і при необхідності може бути легко перетворена на вибрану Вами колекцію. Але іноді, можливо, вам доведеться повернути колекцію (скажімо, через сильні вимоги послідовності), або ви можете повернути колекцію, оскільки ви знаєте, як користувач буде користуватися нею і знаєте, що це найзручніша річ для них.
players.stream()
це саме такий метод, який повертає потік абоненту. Справжнє запитання полягає в тому, чи дійсно ви хочете обмежити абонента в одному переході, а також заборонити йому доступ до вашої колекції черезCollection
API? Можливо, абонент просто хочеaddAll
його до іншої колекції?