Java 在不需要具体化的情况下排列两个流

Java 在不需要具体化的情况下排列两个流,java,java-stream,Java,Java Stream,我有两个流,我必须具体化为两个列表,以从两个流中获得排列: 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(10

我有两个流,我必须具体化为两个列表,以从两个流中获得排列:

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();
}
因此,我具体化了这两个列表,并使用了一个经典循环。但是,我希望通过执行以下步骤来提高性能:

  • 避免实现
    list1
    list2
  • 也可以对
    list1
    list2
    使用parallelStream来更快地进行排列
这可能吗?如果是,怎么做

编辑:

感谢@Andreas提供迄今为止行之有效的解决方案。但是,我想知道如何从两个getAll()流创建置换,而不需要在两者之间具体化它:

// 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));

}
//Permutations'类包含两个permutation-实例。
流所有置换(){
stream1=getAll();
stream2=getAll();
//返回java.lang.IllegalStateException:流已被操作或关闭
返回stream1.flatMap(s1->stream2.map(s2->新排列(s1,s2));
}

您可以这样做:

公共流getAll(){
返回IntStream.iterate(0,d->d-1).limit(1000000).boxed()
.flatMap(l1->IntStream.iterate(0,d->d+1).限制(1000000)
.mapToObj(l2->新排列(l1,l2));
}
调用方可以决定是否使用并行处理:

//顺序
Stream=getAll();
//平行的
Stream=getAll().parallel();

无需调用
sequential()
,因为
iterate()
返回一个新的顺序
IntStream

,您可以这样做:

公共流getAll(){
返回IntStream.iterate(0,d->d-1).limit(1000000).boxed()
.flatMap(l1->IntStream.iterate(0,d->d+1).限制(1000000)
.mapToObj(l2->新排列(l1,l2));
}
调用方可以决定是否使用并行处理:

//顺序
Stream=getAll();
//平行的
Stream=getAll().parallel();

无需调用
sequential()
,因为
iterate()
返回一个新的顺序
IntStream

很抱歉,这是一个输入错误。只有一个
置换
类。该
置换
类包含两个
置换
实例。由于流只读取一次,若其中一个流必须是iter,则不能在不具体化其中一个流的情况下生成交叉联接好了,现在很清楚了,我只需要具体化一个流,然后它就可以工作了。谢谢。
iterate()
生成一个新的流。下面的答案为第一个
IntStream
的每个值重新生成第二个
IntStream
。为什么您突然试图交叉连接两个已经交叉连接的流?
IntStream
生成1000000个值(整数),因此
getAll()
返回的交叉连接流将具有1000000*1000000=1000000000000个值(
Permuation
对象)。如果交叉连接这些,则最终会得到10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000对于它们,假设其中一个流必须多次迭代。好的,现在很清楚,我只需要具体化一个流,然后它就可以工作了。谢谢。
iterate()
生成一个新的流。下面的答案为第一个
IntStream
的每个值重新生成第二个
IntStream
。为什么您突然试图交叉连接两个已经交叉连接的流?
IntStream
生成1000000个值(整数),因此,
getAll()
返回的交叉连接流将有1000000*1000000=1000000000000个值(
Permuation
对象)。如果交叉连接这些对象,最终会得到1000000000000000000个值。这真的是你想要的吗?安德烈亚斯:
mapToObj
(最后一行)不存在,你的意思是
map(..)
,或@nimo23请参阅javadoc。它确实存在。您似乎错过了我删除
框()的事实
从第二个
IntStream
调用。没有必要在
l2
框中添加注释,因为您添加了这样的注释:
Permutation
构造函数参数是
int
,而不是
Integer
。谢谢!所有操作都有效,只有一个问题,我扩展了上面的问题,以更清楚地说明我想要实现的目标。到目前为止,我已经接受了你的答案。再次感谢!经过比较,我得出结论,我将坚持经典for循环,具体化每个IntStream,然后进行迭代。使用经典for循环,我的平均时间为708ms(对于20000个对象)然而,对于带有flatMap和mapToObj的流,我得到了1100ms的平均时间。我看不出使用flatMap解决方案有任何好处。我还尝试了ParallelStream。它甚至会稍微慢一点。但是,谢谢。我学会了…)Andreas:
mapToObj
(最后一行)不存在,你的意思是
map(…)
,或者?@nimo23请参见javadoc。它确实存在。您似乎错过了我删除
框()的事实
从第二个
IntStream
调用。没有必要在
l2
框中添加注释,因为您添加了这样的注释:
Permutation
构造函数参数是
int
,而不是
Integer
。谢谢!所有操作都有效,只有一个问题,我扩展了上面的问题,以更清楚地说明我想要实现的目标。到目前为止,我已经接受了你的答案。再次感谢!经过比较,我得出结论,我将坚持这一原则
// 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));

}