JAVA-STREAM:重用double和DoubleStream

JAVA-STREAM:重用double和DoubleStream,java,stream,java-stream,supplier,Java,Stream,Java Stream,Supplier,我需要一个技巧来解决这个问题,我正在使用Java1.8,我从一个返回DoubleStream对象的方法中检索了一个对象。所以,问题是我不能在流被消耗之后重用它 以下是代码的第一个版本: DoubleStream stream = object.getvalueStream(a,b); if(condtion) stream.map(v -> v * 2); stream.forEach(value -> { // do something } 问题是

我需要一个技巧来解决这个问题,我正在使用Java1.8,我从一个返回DoubleStream对象的方法中检索了一个对象。所以,问题是我不能在流被消耗之后重用它

以下是代码的第一个版本:

 DoubleStream stream = object.getvalueStream(a,b);
 if(condtion)
   stream.map(v -> v * 2);
 stream.forEach(value -> {
        // do something
  }
问题是,一旦条件为真,流就会被消耗,并且我不能重用它。所以我尝试使用一个供应商返回一个来自供应商的doubleStream,并对其进行迭代

但是,当我试图从已经使用的stream对象恢复流时,仍然存在同样的问题

这是我的更新代码:

      DoubleStream stream = object.getvalueStream(a,b);
      if(condtion)
      stream.map(v -> v * 2);
      Supplier>DoubleStream> streamSupplier = () -> DoubleStream.of(stream.toArray());
      streamSupplier.get().forEach(value -> {
           //Do something
但我仍然有同样的问题,因为如果条件为真,我将从已经使用的流创建我的供应商


谢谢您的帮助。

Java中的流无法重用。您应该
收集结果并像这样流两次

List<Double> doubles = object.getvalueStream(a,b).boxed().collect(toList());

if(condition) {
    doubles = doubles.stream().map(v -> v * 2).boxed().collect(toList);
}

// and further processing here
doubles.stream().forEach(v ->
    ...
);
List doubles=object.getvalueStream(a,b).boxed().collect(toList());
如果(条件){
doubles=doubles.stream().map(v->v*2.boxed().collect(toList);
}
//然后在这里进一步处理
doubles.stream().forEach(v->
...
);
如果保留流而不收集流很重要,则可以使用map()。这种方法的唯一缺点是每次都必须检查条件

DoubleStream stream = object.getvalueStream(a,b).map(v-> condition ? v*2 : v).forEach(...);
或者只将正确的流分配给变量

DoubleStream stream = condition ? object.getvalueStream(a,b).map(v->v*2) : object.getvalueStream(a,b).map(v->v*2).forEach(...);
一旦条件为真,流将被消耗,我无法重用它

中间操作(例如,
map
)返回一个新流,因此您需要在中间操作(
map
)之后重新分配该流

注意:终端操作(例如,
foreach
)不会返回流。因此,如果您需要许多终端操作,您应该收集流以便可以重用


另外请注意,如果您希望链接
foreach
peek
)调用,还有一个名为
peek
的中间版本
foreach

您从每个中间操作中获得一个新的
流,因此您应该执行
Stream=Stream.map(…)
但不使用诸如
.forEach(…)
之类的“终端操作”。如果您能解释为什么不感兴趣收集和重用流,可能会更好?执行
n
附加检查而不是一次检查的原因是什么?@m.antkohetwicz只是为了在任务需要时保留流,但没有实际原因。显然,最好是将流收集到列表中,然后根据需要使用它,但不想重复前面的回答。必须进行
n
映射无论如何,额外的条件检查不会对性能产生太大影响,特别是对于分支预测,@wilmol,这显然不是真的,因为当条件为false时,甚至不需要进行单个映射。我们对集合大小和条件统计信息一无所知-您怎么能说它不会影响性能?如果我们有数以十亿计的项目,条件在99%的情况下为真,并且方法在循环中运行,该怎么办?好的,如果条件为假,冗余
v->v
映射会减慢它的速度。但不多。我假设
condition
缓存在
boolean
变量中,所以分支预测应该优化它。我运行了一个JMH基准测试(10次迭代,10亿个元素(
IntStream.range(0,1,1,000,000
))。第一次没有映射操作。第二次映射总是假条件,第三次映射操作只有
v->v
(无条件)。第一次平均5406ms,第二次平均5684ms,第三次平均5656ms。
DoubleStream stream = object.getvalueStream(a,b);
if (condition) {
    stream = stream.map(v -> v * 2);
}
stream.forEach(value -> {
    // do something
}