JAVA-STREAM:重用double和DoubleStream
我需要一个技巧来解决这个问题,我正在使用Java1.8,我从一个返回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 } 问题是
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
}