Lukas Eder..
6
如果你正在缓冲你在一个副本中消耗的元素,但在另一个副本中却没有.
我们duplicate()在jOOλ中实现了一个流方法,这是一个我们创建的开源库,用于改进jOOQ的集成测试.基本上,你可以写:
Tuple2, Seq> desired_streams = Seq.seq(
IntStream.range(1, 100).filter(n -> n % 2 == 0).boxed()
).duplicate();
(注意:我们目前需要打包流,因为我们尚未实现IntSeq)
在内部,有一个LinkedList缓冲区存储从一个流中消耗但从另一个流中消耗的所有值.如果您的两个流以相同的速率消耗,那么这可能是有效的.
以下是算法的工作原理:
static Tuple2, Seq> duplicate(Stream stream) {
final LinkedList gap = new LinkedList<>();
final Iterator it = stream.iterator();
@SuppressWarnings("unchecked")
final Iterator[] ahead = new Iterator[] { null };
class Duplicate implements Iterator {
@Override
public boolean hasNext() {
if (ahead[0] == null || ahead[0] == this)
return it.hasNext();
return !gap.isEmpty();
}
@Override
public T next() {
if (ahead[0] == null)
ahead[0] = this;
if (ahead[0] == this) {
T value = it.next();
gap.offer(value);
return value;
}
return gap.poll();
}
}
return tuple(seq(new Duplicate()), seq(new Duplicate()));
}
事实上,使用jOOλ,你将能够像这样写一个完整的单行:
Tuple2, Seq> desired_streams = Seq.seq(
IntStream.range(1, 100).filter(n -> n % 2 == 0).boxed()
).duplicate()
.map1(s -> s.filter(n -> n % 7 == 0))
.map2(s -> s.filter(n -> n % 5 == 0));
// This will yield 14, 28, 42, 56...
desired_streams.v1.forEach(System.out::println)
// This will yield 10, 20, 30, 40...
desired_streams.v2.forEach(System.out::println);