2015-04-14 12 views
11

Có phải Java 8 Streams các kiểu trả về an toàn cho các phương thức công cộng, ở chỗ nó sẽ không thể thay đổi đối tượng bên dưới cho một luồng từ nó? Ví dụ: nếu tôi có Listreturn list.stream(); thì giá trị trả lại có thể được sử dụng để thay đổi danh sách gốc không?Java 8 có phải là kiểu trả về an toàn không?

Đánh giá từ API, tôi không nghĩ là có thể nhưng muốn xác nhận.

+2

Đọc sau đây và bạn sẽ nhận được một khái niệm tốt về lý do tại sao con suối sẽ không sửa đổi mã nguồn (một bộ sưu tập trong ví dụ của bạn): http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html – alfasin

+4

Bắt luồng từ danh sách không được sửa đổi cấu trúc dữ liệu "chính nó" nhưng nó có thể sửa đổi cấu trúc của nó nội dung nếu nó chứa các đối tượng có thể thay đổi. Nhưng nguyên tắc này là về cấu trúc dữ liệu nói chung anyway. –

Trả lời

13

Có, thật an toàn để làm như vậy. Các luồng không/không nên sửa đổi cấu trúc dữ liệu cơ bản.

Một vài trích đoạn từ java.util.stream.Stream:

Một chuỗi của các yếu tố [& hellip;].

Bộ sưu tập và luồng, trong khi mang một số điểm tương đồng bề ngoài, có các mục tiêu khác nhau. Bộ sưu tập chủ yếu quan tâm đến việc quản lý hiệu quả và truy cập vào các yếu tố của chúng. Ngược lại, các luồng không cung cấp phương tiện để truy cập trực tiếp hoặc điều khiển các phần tử của chúng [& hellip;].

Để duy trì hành vi đúng, [tham số hành vi đối với hoạt động truyền trực tiếp & hellip;] phải không can thiệp (chúng không thay đổi nguồn luồng).

Và từ Package java.util.stream Description:

Streams khác với các bộ sưu tập bằng nhiều cách:

  • Không lưu trữ. Luồng không phải là cấu trúc dữ liệu lưu trữ các phần tử; thay vào đó, nó truyền tải các phần tử từ một nguồn [& hellip;], thông qua một đường dẫn của các phép toán.
  • Chức năng trong tự nhiên. Một hoạt động trên luồng tạo ra kết quả, nhưng không sửa đổi nguồn của nó.

Bạn cũng có thể thấy Non-interference.


[& hellip;] nó sẽ là không thể để biến những đối tượng tiềm ẩn cho một dòng suối từ nó.

Trong khi nó sẽ là thể viết riêng thực hiện của chúng ta về java.util.Stream rằng biến đổi cấu trúc dữ liệu cơ bản, nó sẽ là một lỗi để làm như vậy. ;)


Để trả lời nhận xét của @AlexisC.:

Bắt luồng từ danh sách [& hellip;] có thể sửa đổi nội dung nội dung nếu nội dung đó chứa đối tượng có thể thay đổi.

Đây là điểm công bằng. Nếu chúng ta có một dòng yếu tố mà có thể thay đổi, chúng tôi có thể làm:

myObj.stream().forEach((Foo foo) -> (foo.bar = baz)); 
+0

Ngoại trừ sự phản ánh của khóa học. Tôi đã không thử nó nhưng tôi sẽ rất ngạc nhiên nếu bạn không thể sử dụng sự phản chiếu để truy cập và sửa đổi cấu trúc bên dưới của luồng. – kajacx

+0

Chỉ cần làm rõ, bản thân bộ sưu tập không thể được sửa đổi bởi luồng, nhưng các mục có thể nếu chúng có thể thay đổi. Nếu bạn không muốn các mặt hàng được sửa đổi, hãy biến chúng thành bất biến thông qua cuối cùng và đóng gói. – tmn

+4

@kajacx Có thể lấy một tham chiếu đến cấu trúc dữ liệu cơ bản với sự phản chiếu nhưng điều tương tự có thể được nói cho bất kỳ sự bất biến nào trong Java. Không có gì là bất biến nếu bạn muốn viết một số mã hacky. Tương tự áp dụng cho ví dụ: 'Collections.unmodifiableList'. – Radiodef

Các vấn đề liên quan