gpt4 book ai didi

java - 如何从 Iterator 创建无限 Stream

转载 作者:IT老高 更新时间:2023-10-28 20:45:38 25 4
gpt4 key购买 nike

看看我制作的以下类(class):

public class FibonacciSupplier implements Iterator<Integer> {
private final IntPredicate hasNextPredicate;

private int beforePrevious = 0;
private int previous = 1;

private FibonacciSupplier(final IntPredicate hasNextPredicate) {
this.hasNextPredicate = hasNextPredicate;
}

@Override
public boolean hasNext() {
return hasNextPredicate.test(previous);
}

@Override
public Integer next() {
int result = beforePrevious + previous;
beforePrevious = previous;
previous = result;
return result;
}

public static FibonacciSupplier infinite() {
return new FibonacciSupplier(i -> true);
}

public static FibonacciSupplier finite(final IntPredicate predicate) {
return new FibonacciSupplier(predicate);
}
}

以及它的用法:

public class Problem2 extends Problem<Integer> {
@Override
public void run() {
result = toList(FibonacciSupplier.finite(i -> (i <= 4_000_000)))
.stream()
.filter(i -> (i % 2 == 0))
.mapToInt(i -> i)
.sum();
}

@Override
public String getName() {
return "Problem 2";
}

private static <E> List<E> toList(final Iterator<E> iterator) {
List<E> list = new ArrayList<>();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list;
}
}

我怎样才能创建一个无限 Stream<E> ?

如果我使用 Stream<Integer> infiniteStream = toList(FibonacciSupplier.infinite()).stream() ,可能令人惊讶的是,我永远不会获得无限流。
相反,代码将在创建 list 时永远循环。在底层方法中。

到目前为止,这纯粹是理论上的,但如果我想先跳过无限流中的前 x 个数字,然后将其限制为最后 y 个数字,我绝对可以理解它的必要性,例如:

int x = MAGIC_NUMBER_X;
int y = MAGIC_NUMBER_y;
int sum = toList(FibonacciSupplier.infinite())
.stream()
.skip(x)
.limit(y)
.mapToInt(i -> i)
.sum();

代码永远不会返回结果,应该怎么做?

最佳答案

您的错误是认为您需要一个Iterator 或一个Collection 来创建一个Stream。对于创建无限流,一个方法提供一个接一个的值就足够了。所以对于你的类 FibonacciSupplier 最简单的用法是:

IntStream s=IntStream.generate(FibonacciSupplier.infinite()::next);

或者,如果您更喜欢装箱的值:

Stream<Integer> s=Stream.generate(FibonacciSupplier.infinite()::next);

请注意,在这种情况下,方法不必命名为 next 也不必满足 Iterator 接口(interface)。但它是否与您的类(class)一样并不重要。此外,由于我们刚刚告诉流使用 next 方法作为 Supplier,因此永远不会调用 hasNext 方法。它只是无限的。

使用 Iterator 创建一个有限流有点复杂:

Stream<Integer> s=StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
FibonacciSupplier.finite(intPredicate), Spliterator.ORDERED),
false);

在这种情况下,如果您想要一个具有未装箱 int 值的有限 IntStream,您的 FibonacciSupplier 应该实现 PrimitiveIterator.OfInt.

关于java - 如何从 Iterator<E> 创建无限 Stream<E>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21956515/

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