如何创建无限流<E>出迭代器<E>?

时间:2023-01-14
本文介绍了如何创建无限流<E>出迭代器<E>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

看看我制作的以下课程:

Looking at the following class I've made:

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;
    }
}

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

How would I be able to create an infinite Stream<E>?

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

If I were to use Stream<Integer> infiniteStream = toList(FibonacciSupplier.infinite()).stream(), I would, possibly surprisingly, never get an infinite stream.
Instead the code would loop forever in the creation of the list in an underlying method.

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

This so far is purely theoretical, but I can definately understand the need for it if I would want to first skip the first x numbers from an infinite stream, and then limit it by the last y numbers, something like:

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

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

The code would not ever return a result, how should it be done?

推荐答案

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

Your mistake is to think that you need an Iterator or a Collection to create a Stream. For creating an infinite stream, a single method providing one value after another is enough. So for your class FibonacciSupplier the simplest use is:

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

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

or, if you prefer boxed values:

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

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

Note that in this case the method does not have to be named next nor fulfill the Iterator interface. But it doesn’t matter if it does as with your class. Further, as we just told the stream to use the next method as a Supplier, the hasNext method will never be called. It’s just infinite.

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

Creating a finite stream using your Iterator is a bit more complicated:

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

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

In this case if you want a finite IntStream with unboxed int values your FibonacciSupplier should implement PrimitiveIterator.OfInt.

这篇关于如何创建无限流&lt;E&gt;出迭代器&lt;E&gt;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:是否有与 Python 的“枚举"函数等效的 Java? 下一篇:List.iterator() 是线程安全的吗?

相关文章

最新文章