Reputation: 5700
I have two streams which I must materialize into two lists to get the permutations from both streams:
public Stream<Permutation> getAll() {
Stream.Builder<Permutation> all = Stream.builder();
// unfortunately, I must collect it into a list
var list1 = IntStream.iterate(0, d -> d - 1).limit(1000000).boxed().collect(Collectors.toList());
var list2 = IntStream.iterate(0, d -> d + 1).limit(1000000).boxed().collect(Collectors.toList());
// I must use a classic loop (and cannot operate on those streams) to avoid java.lang.IllegalStateException
for(var l1: list1) {
for(var l2: list2) {
// the permutation class consists of two int properties
all.add(new Permutation(l1, l2));
}
}
return all.build();
}
Is there a way to avoid to materialize list1
and list2
and operate only on those streams to return the permutations? I have tried it but I get
java.lang.IllegalStateException: stream has already been operated upon or closed
Therefore I have materialized the two lists and used a classic loop. However, I would like to improve the performance by doing the following steps:
list1
and list2
list1
and list2
to get the permutations fasterIs this possible? If so, how?
EDIT:
Thanks to @Andreas for the solution which works so far. However, I wonder how I can create a permutation from two getAll()-streams without the need to materialize it in between:
// The `Permutations` class holds two `Permuation`-instances.
Stream<Permutations> allPermutations(){
Stream<Permutation> stream1 = getAll();
Stream<Permutation> stream2 = getAll();
// returns java.lang.IllegalStateException: stream has already been operated upon or closed
return stream1.flatMap(s1->stream2.map(s2->new Permutations(s1,s2));
}
Upvotes: 0
Views: 189
Reputation: 159127
You can do it like this:
public Stream<Permutation> getAll() {
return IntStream.iterate(0, d -> d - 1).limit(1000000).boxed()
.flatMap(l1 -> IntStream.iterate(0, d -> d + 1).limit(1000000)
.mapToObj(l2 -> new Permutation(l1, l2)));
}
The caller can decide whether or not to use parallel processing:
// Sequential
Stream<Permutation> stream = getAll();
// Parallel
Stream<Permutation> stream = getAll().parallel();
No need to call sequential()
, since iterate()
returns a new sequential IntStream
.
Upvotes: 2