Is it possible to use Streams.intRange function?

后端 未结 3 1572
挽巷
挽巷 2021-01-16 07:07

I wanted to use Streams.intRange(int start, int end, int step) to achieve reverse ordered stream. However it seems that java.util.Streams class is no longer available (howev

3条回答
  •  再見小時候
    2021-01-16 07:20

    Both solutions proposed so far don't respect parallelization. The spliterator proposed by @fge does not parallelize at all. The iterate-based stream proposed by @RealSkeptic will use buffered parallelization (some numbers will be loaded into the intermediate array and handed over to the another thread) which is not always effective.

    There's quite simple alternative solution which provides normal parallelization (here end is exclusive):

    public static IntStream intRange(int start, int end, int step ) {
        int limit = (end-start+step-(step>>31|1))/step;
        return IntStream.range(0, limit).map(x -> x * step + start);
    }
    

    Or if you want to take into account really weird inputs like intRange(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE):

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

提交回复
热议问题