如何使用索引而不是前一个元素生成流?

时间:2017-09-20 05:58:48

标签: java java-stream

如何生成" new"数据?具体来说,我希望能够创建包含不可逆功能的数据。 如果我想创建一个流from an Array 我做了

Stream.of(arr)

From a collection

col.stream()

constant stream可以使用lambda表达式

Stream.generate(() -> "constant")

最后一个输入(任何可逆功能)的stream based可以通过

实现
Stream.iterate(0, x -> x + 2)

但是如果我想创建一个更通用的生成器(比如输出数字是否会被三个分解:0,0,1,0,0,1,0,0,1 ...)而不创建新的类。

主要问题是我需要有一些方法将索引输入到lambda中,因为我想要一个模式,而不是依赖于函数的最后一个输出。

注意: someStream.limit(length)可能会用来停止流的长度,所以无限的流生成器​​实际上就是我要找的。

2 个答案:

答案 0 :(得分:2)

如果您希望获取索引函数的无限流,可以考虑使用

创建“几乎无限”流
IntStream.rangeClosed(0, Integer.MAX_VALUE).map(index -> your lambda)

RESP。

IntStream.rangeClosed(0, Integer.MAX_VALUE).mapToObj(index -> your lambda)

表示Stream而不是IntStream

这不是真正的无限,但没有int值来表示Integer.MAX_VALUE之后的索引,所以当你遇到索引时你有一个语义问题需要解决

此外,当使用LongStream.rangeClosed(0, Long.MAX_VALUE).map(index -> yourLambda)而每个元素评估只需要一纳秒时,处理所有元素将花费近三百年的时间。

但是,当然,有一种方法可以使用

创建一个真正无限的流
Stream.iterate(BigInteger.ZERO, BigInteger.ONE::add).map(index -> yourLambda)

如果你的处理能够达到那么远,那么一旦索引无法再在堆内存中显示,它可能会永远运行,或者更有可能用OutOfMemoryError进行拯救。

请注意,使用range[Closed]构建的流可能比使用Stream.iterate构建的流更有效。

答案 1 :(得分:0)

你可以做这样的事情

    AtomicInteger counter = new AtomicInteger(0);

    Stream<Integer> s = Stream.generate(() -> counter.getAndIncrement());