Java 是否可以使用Streams.intRange功能?

Java 是否可以使用Streams.intRange功能?,java,java-8,java-stream,Java,Java 8,Java Stream,我想使用Streams.intRange(int start,int end,int step)来实现逆序流。然而,java.util.Streams类似乎不再可用(但它仍然在标准库的rt.jar中)。这个方法是在其他类中还是被其他类所取代?JDK中确实不再有这样的方法了;您可以得到的下一个最接近的是IntStream.range()但这只会一步一步地进行 这里的一个解决方案是实现您自己的拆分器;例如,类似这样的东西(非常粗糙;可以改进!): 然后,您将使用从上述类的实例生成流。JDK中确实不再

我想使用Streams.intRange(int start,int end,int step)来实现逆序流。然而,java.util.Streams类似乎不再可用(但它仍然在标准库的rt.jar中)。这个方法是在其他类中还是被其他类所取代?

JDK中确实不再有这样的方法了;您可以得到的下一个最接近的是
IntStream.range()
但这只会一步一步地进行

这里的一个解决方案是实现您自己的
拆分器;例如,类似这样的东西(非常粗糙;可以改进!):


然后,您将使用从上述类的实例生成流。

JDK中确实不再有这样的方法;下一个最接近的方法是
IntStream.range()
,但这只会一步一步地进行

这里的一个解决方案是实现您自己的
拆分器;例如,类似这样的东西(非常粗糙;可以改进!):


然后,您将使用从上述类的实例生成流。

您可以基于无限流创建流:

public static IntStream intRange(int start, int end, int step ) {
    if ( step == 0 ) {
        throw new IllegalArgumentException("Cannot iterate with a step of zero");
    }
    final int limit = (end - start + step) / step;
    if ( limit < 0 ) {
        return IntStream.empty();
    }
    return IntStream.iterate(start, x -> x + step )
                    .limit( limit );
}
可能的用途:

intRange(8 ,2, -2).forEach(System.out::println);
输出:

8
6
4
2

您可以基于无限流创建它:

public static IntStream intRange(int start, int end, int step ) {
    if ( step == 0 ) {
        throw new IllegalArgumentException("Cannot iterate with a step of zero");
    }
    final int limit = (end - start + step) / step;
    if ( limit < 0 ) {
        return IntStream.empty();
    }
    return IntStream.iterate(start, x -> x + step )
                    .limit( limit );
}
可能的用途:

intRange(8 ,2, -2).forEach(System.out::println);
输出:

8
6
4
2

目前提出的两种解决方案都不考虑并行化。@fge提出的拆分器根本不并行。@realponsum提出的基于迭代的流将使用缓冲并行化(一些数字将被加载到中间数组并交给另一个线程),这并不总是有效的

有一个非常简单的替代解决方案,它提供了正常的并行化(这里
end
是专用的):

或者,如果您想考虑非常奇怪的输入,如
内部消息(Integer.MAX\u值、Integer.MIN\u值、Integer.MIN\u值)


目前提出的两种解决方案都不考虑并行化。@fge提出的拆分器根本不并行。@realponsum提出的基于迭代的流将使用缓冲并行化(一些数字将被加载到中间数组并交给另一个线程),这并不总是有效的

有一个非常简单的替代解决方案,它提供了正常的并行化(这里
end
是专用的):

或者,如果您想考虑非常奇怪的输入,如
内部消息(Integer.MAX\u值、Integer.MIN\u值、Integer.MIN\u值)


此链接可能对您的需求有所帮助:
http://stackoverflow.com/questions/24010109/java-8-stream-reverse-order
此链接可能对您的需求有所帮助:
http://stackoverflow.com/questions/24010109/java-8-stream-reverse-order
足够近。很遗憾,此功能已被删除。距离足够近。遗憾的是,此函数已被删除。舍入误差太大,例如,
intRange(0,9,2).forEach(System.out::println)不会打印
8
。除此之外,此解决方案也是唯一一个具有可预测大小的解决方案,它在内部甚至在顺序操作中使用,例如
toArray()
。要想出一个对两个方向都有效的
限制
计算并不容易。到目前为止,我得到的“最简单的”是
limit=(end-start+step-(step>>31 | 1))/step
@Holger,谢谢。我的缺点是,我没有彻底测试极限。复制了你的公式now@Holger实际上,当涉及到
intRange(Integer.MAX\u值、Integer.MIN\u值、Integer.MIN\u值)
等输入时,问题更加棘手。我编辑了答案,添加了我在解决方案上的最大努力,该解决方案考虑了所有的角落案例。不是很漂亮,但到目前为止我所有的测试都通过了。我不想使用
long
类型,因为类似的
long-range
方法也应该以相同的方式实现。舍入误差太大,例如
intRange(0,9,2).forEach(System.out::println)不会打印
8
。除此之外,此解决方案也是唯一一个具有可预测大小的解决方案,它在内部甚至在顺序操作中使用,例如
toArray()
。要想出一个对两个方向都有效的
限制
计算并不容易。到目前为止,我得到的“最简单的”是
limit=(end-start+step-(step>>31 | 1))/step
@Holger,谢谢。我的缺点是,我没有彻底测试极限。复制了你的公式now@Holger实际上,当涉及到
intRange(Integer.MAX\u值、Integer.MIN\u值、Integer.MIN\u值)
等输入时,问题更加棘手。我编辑了答案,添加了我在解决方案上的最大努力,该解决方案考虑了所有的角落案例。不是很漂亮,但到目前为止我所有的测试都通过了。我不想使用
long
类型,因为类似的
longRange
方法也应该以相同的方式实现。
public static IntStream intRange(int startInclusive, int endExclusive, int step) {
    if(step == 0)
        throw new IllegalArgumentException("step = 0");
    if(step == 1)
        return IntStream.range(startInclusive, endExclusive);
    if(step == -1) {
        // Handled specially as number of elements can exceed Integer.MAX_VALUE
        int sum = endExclusive+startInclusive;
        return IntStream.range(endExclusive, startInclusive).map(x -> sum - x);
    }
    if((endExclusive > startInclusive ^ step > 0) || endExclusive == startInclusive)
        return IntStream.empty();
    int limit = (endExclusive-startInclusive)*Integer.signum(step)-1;
    limit = Integer.divideUnsigned(limit, Math.abs(step));
    return IntStream.rangeClosed(0, limit).map(x -> x * step + startInclusive);
}