Câu trả lời là, như mọi khi, "nó phụ thuộc". Nó phụ thuộc vào mức độ lớn của bộ sưu tập được trả lại. Nó phụ thuộc vào việc kết quả có thay đổi theo thời gian hay không và mức độ quan trọng của kết quả trả về là như thế nào. Và nó phụ thuộc rất nhiều vào cách người dùng có khả năng sử dụng câu trả lời.
Đầu tiên, lưu ý rằng bạn luôn có thể nhận được Bộ sưu tập từ một luồng và ngược lại:
// If API returns Collection, convert with stream()
getFoo().stream()...
// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());
Vì vậy, câu hỏi là, cái nào hữu ích hơn cho người gọi của bạn.
Nếu kết quả của bạn có thể là vô hạn, chỉ có một lựa chọn: Luồng.
Nếu kết quả của bạn có thể rất lớn, có lẽ bạn thích Stream, vì có thể không có bất kỳ giá trị nào trong việc hiện thực hóa tất cả cùng một lúc và làm như vậy có thể tạo ra áp lực lớn.
Nếu tất cả người gọi sẽ làm là lặp qua nó (tìm kiếm, lọc, tổng hợp), bạn nên chọn Stream, vì Stream đã tích hợp sẵn và không cần thiết phải thực hiện một bộ sưu tập (đặc biệt là nếu người dùng có thể không xử lý toàn bộ kết quả.) Đây là một trường hợp rất phổ biến.
Ngay cả khi bạn biết rằng người dùng sẽ lặp đi lặp lại nhiều lần hoặc thay vào đó, bạn vẫn có thể muốn trả về Luồng thay vào đó, vì thực tế đơn giản là bất kỳ Bộ sưu tập nào bạn chọn để đặt nó vào (ví dụ: ArrayList) có thể không phải là hình thức họ muốn, và sau đó người gọi phải sao chép nó. nếu bạn trả về một luồng, họ có thể làm collect(toCollection(factory))
và lấy nó ở dạng chính xác mà họ muốn.
Các trường hợp "thích Stream" ở trên hầu hết xuất phát từ thực tế là Stream linh hoạt hơn; bạn có thể liên kết muộn với cách bạn sử dụng nó mà không phải chịu các chi phí và ràng buộc của việc cụ thể hóa nó thành Bộ sưu tập.
Trường hợp bạn phải trả lại Bộ sưu tập là khi có các yêu cầu về tính nhất quán cao và bạn phải tạo ra một ảnh chụp nhanh nhất quán của mục tiêu đang di chuyển. Sau đó, bạn sẽ muốn đặt các yếu tố vào một bộ sưu tập sẽ không thay đổi.
Vì vậy, tôi sẽ nói rằng hầu hết thời gian, Stream là câu trả lời đúng - nó linh hoạt hơn, nó không áp đặt chi phí vật chất thường không cần thiết và có thể dễ dàng chuyển thành Bộ sưu tập bạn chọn nếu cần. Nhưng đôi khi, bạn có thể phải trả lại Bộ sưu tập (giả sử, do yêu cầu về tính nhất quán cao) hoặc bạn có thể muốn trả lại Bộ sưu tập vì bạn biết người dùng sẽ sử dụng nó như thế nào và biết đây là điều thuận tiện nhất cho họ.
players.stream()
chỉ là một phương thức trả về một luồng cho người gọi. Câu hỏi thực sự là, bạn có thực sự muốn hạn chế người gọi đến một giao dịch đơn lẻ và cũng từ chối anh ta truy cập vào bộ sưu tập của bạn quaCollection
API không? Có lẽ người gọi chỉ muốnaddAll
nó đến một bộ sưu tập khác?