ReactiveX有一个名为Scan的Very Neat运算符,它类似于reduce,但它会发出每个中间累加器。
我将如何使用Java Streams完成此任务? Stream#reduce
不是我想要的,因为它返回T
:
T reduce(T identity, BinaryOperator<T> accumulator)
我想要返回Stream<T>
,而流的每个项目都是在每次调用T
时返回的accumulator
:
Stream.of(1, 2, 3)
.myScan(0, (accumulator, i) -> accumulator + i)
.collect(Collectors.toList()); // [1, 3, 6]
我可以做一些la脚的事情,例如减少List
,然后再转换回Stream
,但这很丑。
答案 0 :(得分:1)
流不支持此操作。您可以将其转换为迭代器,然后在其中进行处理,然后转换回流,但是流没有内置的功能可以做到这一点。
答案 1 :(得分:1)
尝试StreamEx。我认为它提供了所需的提取API:
# 2)
# Flow file
Flow.create(environment: :probe) do
import 'vreg'
end
# Test interface file
def import(sub_flow, options = {})
sub_flow = "../sub_flows/#{sub_flow}"
super(sub_flow, options)
end
答案 2 :(得分:0)
您可以尝试从否则受挫的side-effects中受益。由于您的目标是处理流并继续处理流,因此我们可以使用map
方法来实现这一点。以下代码利用了副作用。
public class Scan {
public static void main(String[] args) {
Accumulator accumulator = new Accumulator();
Stream<Integer> originalStream = Stream.of(1, 2, 3);
Stream<Integer> scannedStream = originalStream
.map(i -> accumulator.accumulate(i));
List<Integer> list = scannedStream
.collect(Collectors.toList()); // [1, 3, 6]
for (Integer i : list) {
System.out.println(i);
}
}
private static class Accumulator {
private int value;
public int accumulate(int i) {
return value += i;
}
}
}
Accumulator
可以用Function
替换,以用于不同的 scan 操作。
但是您必须意识到限制和担忧(例如线程安全)。
答案 3 :(得分:0)
java-stream的最大问题是,它被高估了,并且被认为是解决与Collection的任何相关的所有问题的灵丹妙药。
已构建此API以支持元素的顺序处理。尚无任何类似Stream的方法执行以下代码段。而且,此API难以扩展。
这是你在说什么:
.sidenav{
width: 200px; /*or whatever width you want*/
left: -200px;
position: fixed;
}
.sidenav.open{
left: 0;
}
.body-wrap {
position: relative;
left: 0;
overflow: hidden;
}
.body-wrap.open {
left: 200px;
}
这是使用AtomicInteger
的一种解决方法,它使您可以在执行List<Integer> list = new ArrayList<>();
Stream.of(1, 2, 3).reduce(0, (t, u) -> {
final Integer s = t + u;
list.add(s);
return s;
});
System.out.println(list); // prints [1, 3, 6]
之后继续进行流式传输:
map(..)
有时您必须使用不同的方式。