gpt4 book ai didi

java - 如何实现用于流式传输斐波那契数的 Spliterator?

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:35 27 4
gpt4 key购买 nike

我正在玩 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com