2016-03-28 30 views
24

Tôi đang học các tính năng Java 8 mới, và trong khi thử nghiệm với các luồng (java.util.stream.Stream) và các bộ thu, tôi nhận ra rằng một luồng không thể được sử dụng hai lần .. có cách nào để sử dụng lại nó không?Có cách nào để tái sử dụng Luồng trong java 8 không?

+0

Vâng, con suối có thể được tái sử dụng, chỉ khi bất kỳ ứng dụng nào không gọi bất kỳ thao tác đầu cuối nào trên đó. –

+0

Bản sao có thể sao chép của luồng [Sao chép luồng để tránh "đã được vận hành theo hoặc đóng" (java 8)] (http://stackoverflow.com/questions/23860533/copy-a-stream-to-avoid-stream- đã-đã-được-vận hành-khi-hoặc-đóng-java-8) – Andrejs

Trả lời

32

Từ documentation:

Một dòng nên được phẫu thuật (cách gọi một hoạt động dòng trung gian hoặc thiết bị đầu cuối) chỉ một lần.

Việc triển khai luồng có thể ném IllegalStateException nếu phát hiện thấy luồng đang được sử dụng lại.

Vì vậy, câu trả lời là không, luồng không được sử dụng lại.

1

Toàn bộ ý tưởng của Luồng là nó một lần. Điều này cho phép bạn tạo các nguồn không thể tái nhập (ví dụ, đọc các dòng từ kết nối mạng) mà không cần lưu trữ trung gian. Tuy nhiên, nếu bạn muốn sử dụng lại nội dung Luồng, bạn có thể đưa nội dung đó vào bộ sưu tập trung gian để lấy "bản in ra giấy":

Stream<MyType> stream = // get the stream from somewhere 
List<MyType> list = stream.collect(Collectors.toList()); // materialize the stream contents 
list.stream().doSomething // create a new stream from the list 
list.stream().doSomethingElse // create one more stream from the list 

Nếu bạn không muốn thực hiện luồng, trong một số trường hợp là cách để thực hiện một số việc với cùng một luồng cùng một lúc. Ví dụ: bạn có thể tham khảo câu hỏi this hoặc this để biết chi tiết.

23

Nếu bạn muốn có tác dụng sử dụng lại luồng, bạn có thể bao bọc biểu thức luồng trong Nhà cung cấp và gọi myStreamSupplier.get() bất cứ khi nào bạn muốn một hình mới. Ví dụ:

Supplier<Stream<String>> sup =() -> 
     someList.stream(); 
List<String> nonEmptyStrings = sup.get().filter(s -> !s.isEmpty()).collect(Collectors.toList()); 
Set<String> uniqueStrings = sup.get().collect(Collectors.toSet()); 
+1

Điều này không tái sử dụng luồng. Nhà cung cấp chỉ tạo một luồng mới để sử dụng mỗi khi được gọi. – axiopisty

+5

Đó là lý do tại sao Hank D nói "hiệu ứng của". Nó vẫn còn mã sạch hơn và tái sử dụng hơn. – Andrejs

9

Như những người khác đã nói "không, bạn không thể".

Nhưng nó là hữu ích để nhớ tiện dụng summaryStatistics() cho nhiều thao tác cơ bản:

Vì vậy, thay vì:

List<Person> personList = getPersons(); 

personList.stream().mapToInt(p -> p.getAge()).average().getAsDouble(); 
personList.stream().mapToInt(p -> p.getAge()).min().getAsInt(); 
personList.stream().mapToInt(p -> p.getAge()).max().getAsInt(); 

Bạn có thể:

// Can also be DoubleSummaryStatistics from mapToDouble() 

IntSummaryStatistics stats = personList.stream() 
             .mapToInt(p-> p.getAge()) 
             .summaryStatistics(); 

stats.getAverage(); 
stats.getMin(); 
stats.getMax(); 
Các vấn đề liên quan