Java – ストリームは既に操作されているか、閉じています
Java 8では、https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html[Stream]は再利用できません。一度使用または使用されると、ストリームは閉鎖される。
1.例 – ストリームは閉じています!
次の例を見てみると、「ストリームが閉じている」という「IllegalStateException」がスローされます。
TestJava8.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);
}
}
出力
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.例 – ストリームを再利用する
何らかの理由で、実際にストリームを再利用したい場合は、次の `Supplier`ソリューションを試してみてください。
TestJava8.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);
}
}
出力
a b c d e 1
各 `get()`は新しいストリームを返します。