[Java 8] – Lỗi Stream has already been operated upon or closed

Chào các bạn, trong bài viết này, chúng ta sẽ cùng tìm hiểu về cách tái sử dụng Stream trong Java 8

Trong Java 8, không thể sử tái dụng Stream, nói cách khác, Stream sẽ được đóng sau khi sử dụng xong.

1. Ví dụ về Stream bị đóng!

Theo dõi ví dụ, sẽ thấy được chương trình quăng ra lỗi IllegalStateException

TestJava8.java
Java:
package com.mkyong.java8;

import java.util.Arrays;
import java.util.stream.Stream;

public class TestJava8 {

    public static void main(String[] args) {

        String[] array = {"a", "b", "c", "d", "e"};
        Stream<String> stream = Arrays.stream(array);

        // loop a stream
        stream.forEach(x -> System.out.println(x));

        // reuse it to filter again! throws IllegalStateException
        long count = stream.filter(x -> "b".equals(x)).count();
        System.out.println(count);

    }
}
Kết quả
Code:
java.lang.IllegalStateException: stream has already been operated upon or closed
    at java.util.stream.AbstractPipeline.(AbstractPipeline.java:203)
    at java.util.stream.ReferencePipeline.(ReferencePipeline.java:94)
    at java.util.stream.ReferencePipeline$StatelessOp.(ReferencePipeline.java:618)
    at java.util.stream.ReferencePipeline$2.(ReferencePipeline.java:163)
    at java.util.stream.ReferencePipeline.filter(ReferencePipeline.java:162)
    at com.hostingcompass.whois.range.run.TestJava8.main(TestJava8.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
2. Ví dụ về tái sử dụng Stream

Với lý do nào đó, bạn muốn tái sử dụng Stream thì có thể sử dụng giải pháp như sau

TestJava8.java
Java:
package com.mkyong.java8;

import java.util.function.Supplier;
import java.util.stream.Stream;

public class TestJava8 {

    public static void main(String[] args) {

        String[] array = {"a", "b", "c", "d", "e"};

        Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);

        //get new stream
        streamSupplier.get().forEach(x -> System.out.println(x));

        //get another new stream
        long count = streamSupplier.get().filter(x -> "b".equals(x)).count();
        System.out.println(count);

    }

}
Kết quả
Code:
a
b
c
d
e
1
Mỗi khi gọi phương thức get(), sẽ có một Stream mới được tạo ra

Vì sao?
Tôi có thể biết lý do tại sao bạn cần sử dụng lại một luồng để thử nghiệm không?


Cám ơn các bạn đã theo dõi. Hẹn gặp lại các bạn trong các bài viết sau :)

Bài viết tham khảo tại: https://mkyong.com/java8/java-stream-has-already-been-operated-upon-or-closed
 
Sửa lần cuối:

Bình luận