我正在玩 Java 8 Spliterator并创建了一个将斐波那契数字流式传输到给定的 n。所以对于斐波那契数列 0, 1, 1, 2, 3, 5, 8, ...
n fib(n)
-----------
-1 0
1 0
2 1
3 1
4 2
以下是我的实现,它在用完堆栈内存之前打印一堆 1。你能帮我找到错误吗? (我认为它没有推进 currentIndex
但我不确定将其设置为什么值)。
编辑 1:如果您决定回答,请保持与问题的相关性。这个问题不是关于高效的斐波那契数生成;这是关于学习 split 器。
斐波那契拆分器:
@RequiredArgsConstructor
public class FibonacciSpliterator implements Spliterator<FibonacciPair> {
private int currentIndex = 3;
private FibonacciPair pair = new FibonacciPair(0, 1);
private final int n;
@Override
public boolean tryAdvance(Consumer<? super FibonacciPair> action) {
// System.out.println("tryAdvance called.");
// System.out.printf("tryAdvance: currentIndex = %d, n = %d, pair = %s.\n", currentIndex, n, pair);
action.accept(pair);
return n - currentIndex >= 2;
}
@Override
public Spliterator<FibonacciPair> trySplit() {
// System.out.println("trySplit called.");
FibonacciSpliterator fibonacciSpliterator = null;
if (n - currentIndex >= 2) {
// System.out.printf("trySplit Begin: currentIndex = %d, n = %d, pair = %s.\n", currentIndex, n, pair);
fibonacciSpliterator = new FibonacciSpliterator(n);
long currentFib = pair.getMinusTwo() + pair.getMinusOne();
long nextFib = pair.getMinusOne() + currentFib;
fibonacciSpliterator.pair = new FibonacciPair(currentFib, nextFib);
fibonacciSpliterator.currentIndex = currentIndex + 3;
// System.out.printf("trySplit End: currentIndex = %d, n = %d, pair = %s.\n", currentIndex, n, pair);
}
return fibonacciSpliterator;
}
@Override
public long estimateSize() {
return n - currentIndex;
}
@Override
public int characteristics() {
return ORDERED | IMMUTABLE | NONNULL;
}
}
斐波那契对:
@RequiredArgsConstructor
@Value
public class FibonacciPair {
private final long minusOne;
private final long minusTwo;
@Override
public String toString() {
return String.format("%d %d ", minusOne, minusTwo);
}
}
用法:
Spliterator<FibonacciPair> spliterator = new FibonacciSpliterator(5);
StreamSupport.stream(spliterator, true)
.forEachOrdered(System.out::print);
最佳答案
除了您的代码不完整之外,您的 tryAdvance
方法中至少有两个错误是可识别的。首先,你实际上并没有取得任何进步。您没有修改拆分器的任何状态。其次,您无条件地调用操作的 accept
方法,这与您返回的是条件值而不是 true
的事实不符。
tryAdvance
的目的是:
- 顾名思义,尝试前进,即计算下一个值
- 如果有下一个值,调用
action.accept
并返回true
- 否则只返回
false
进一步注意,您的trySplit()
看起来不太有说服力,我什至不知道从哪里开始。你最好继承 AbstractSpliterator
而不是实现自定义 trySplit()
。无论如何,您的操作不会从并行执行中受益。使用该源构建的流只有在将其与安静且昂贵的按元素操作链接在一起时才能从并行执行中获得优势。
关于java - 如何实现用于流式传输斐波那契数的 Spliterator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34787295/