Jawabannya, seperti biasa, "itu tergantung". Itu tergantung pada seberapa besar koleksi yang dikembalikan. Itu tergantung pada apakah hasilnya berubah dari waktu ke waktu, dan seberapa penting konsistensi dari hasil yang dikembalikan. Dan itu sangat tergantung pada bagaimana pengguna cenderung menggunakan jawabannya.
Pertama, perhatikan bahwa Anda selalu bisa mendapatkan Koleksi dari Stream, dan sebaliknya:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
Jadi pertanyaannya adalah, mana yang lebih bermanfaat bagi penelepon Anda.
Jika hasil Anda mungkin tidak terbatas, hanya ada satu pilihan: Streaming.
Jika hasil Anda mungkin sangat besar, Anda mungkin lebih suka Stream, karena mungkin tidak ada nilai apa pun dalam mewujudkannya sekaligus, dan melakukan hal itu dapat menciptakan tekanan tumpukan yang signifikan.
Jika semua yang akan dilakukan pemanggil adalah mengulanginya (pencarian, filter, agregat), Anda harus memilih Stream, karena Stream sudah memiliki bawaan ini dan tidak perlu mematerialisasi koleksi (terutama jika pengguna mungkin tidak memproses seluruh hasil.) Ini adalah kasus yang sangat umum.
Bahkan jika Anda tahu bahwa pengguna akan mengulanginya beberapa kali atau mempertahankannya, Anda masih mungkin ingin mengembalikan Stream sebagai gantinya, karena fakta sederhana bahwa Koleksi apa pun yang Anda pilih untuk dimasukkan ke dalamnya (mis., ArrayList) mungkin bukan formulir yang mereka inginkan, dan kemudian pemanggil harus menyalinnya. jika Anda mengembalikan aliran, mereka dapat melakukannya collect(toCollection(factory))
dan mendapatkannya dalam bentuk yang mereka inginkan.
Kasus "prefer Stream" di atas sebagian besar berasal dari fakta bahwa Stream lebih fleksibel; Anda dapat terlambat mengikat ke bagaimana Anda menggunakannya tanpa menimbulkan biaya dan kendala mewujudkannya ke Koleksi.
Satu-satunya kasus di mana Anda harus mengembalikan Koleksi adalah ketika ada persyaratan konsistensi yang kuat, dan Anda harus menghasilkan snapshot konsisten dari target yang bergerak. Kemudian, Anda akan ingin memasukkan elemen ke dalam koleksi yang tidak akan berubah.
Jadi saya akan mengatakan bahwa sebagian besar waktu, Stream adalah jawaban yang tepat - lebih fleksibel, tidak memaksakan biasanya biaya materialisasi yang tidak perlu, dan dapat dengan mudah diubah menjadi Koleksi pilihan Anda jika diperlukan. Tetapi kadang-kadang, Anda mungkin harus mengembalikan Koleksi (katakanlah, karena persyaratan konsistensi yang kuat), atau Anda mungkin ingin mengembalikan Koleksi karena Anda tahu bagaimana pengguna akan menggunakannya dan tahu ini adalah hal yang paling nyaman bagi mereka.
players.stream()
hanyalah metode yang mengembalikan aliran ke pemanggil. Pertanyaan sebenarnya adalah, apakah Anda benar-benar ingin membatasi penelepon ke satu traversal, dan juga menolaknya akses ke koleksi Anda melaluiCollection
API? Mungkin penelepon hanya ingin keaddAll
koleksi lain?