Reputation: 5392
I am trying to compute Prime numbers with Java8 streams, but I get into an IllegalStateException : stream has already been operated upon or closed.
This is my code :
package experimentations.chapter02;
import java.util.stream.Stream;
public class PrimesStream {
public static void main(String[] args) {
Stream.iterate(0, e-> e+1).filter(PrimesStream::isPrime).limit(10).forEach(System.out::println);
}
public static boolean isPrime(int i){
if (i < 2) return false;
Stream<Integer> stream = Stream.iterate(2, e -> e+1);
stream.limit(i - 2);
return !stream.anyMatch(divisor -> i%divisor == 0);
}
}
And this is the stacktrace :
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
at java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:449)
at experimentations.chapter02.PrimesStream.isPrime(PrimesStream.java:14)
at experimentations.chapter02.PrimesStream$$Lambda$2/918221580.test(Unknown Source)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.Spliterators$IteratorSpliterator.tryAdvance(Spliterators.java:1812)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:529)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:516)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at experimentations.chapter02.PrimesStream.main(PrimesStream.java:7)
I have the feeling that this is because I am trying to apply a stream call into another, but even with this thought, I don't know what is the simpliest workaround.
Upvotes: 1
Views: 3626
Reputation: 948
Here is the example code that causes this exception.
List<Person> people = Arrays.asList(
new Person("Bob", 17),
new Person("Dave", 23),
new Person("Joe", 32));
Stream<String> nameStream = people.stream()
.filter(person -> person.getAge() > 21)
.map(Person::getName);
nameStream.forEach(System.out::println);
// When stream values are gone, they are gone. Let’s try again:
nameStream.forEach(System.out::println);
java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
So, you can do only one operation at max on streams
Check this for more about java8 features.
Upvotes: 0
Reputation: 69259
You need to be chaining your stream methods, that will fix it, so your isPrime
should be like:
return !Stream.iterate(2, e -> e + 1)
.limit(i - 1)
.anyMatch(divisor -> i % divisor == 0);
Upvotes: 2