When should I use IntStream.range in Java?

前端 未结 7 1949
盖世英雄少女心
盖世英雄少女心 2020-12-29 01:34

I would like to know when I can use IntStream.range effectively. I have three reasons why I am not sure how useful IntStream.range is.

(Ple

相关标签:
7条回答
  • 2020-12-29 01:56

    It totally depends on the use case. However, the syntax and stream API adds lot of easy one liners which can definitely replace the conventional loops.

    IntStream is really helpful and syntactic sugar in some cases,

    IntStream.range(1, 101).sum();
    IntStream.range(1, 101).average();
    IntStream.range(1, 101).filter(i -> i % 2 == 0).count();
    //... and so on
    

    Whatever you can do with IntStream you can do with conventional loops. As one liner is more precise to understand and maintain.

    Still for negative loops we can not use IntStream#range, it only works in positive increment. So following is not possible,

    for(int i = 100; i > 1; i--) {
        // Negative loop
    }
    
    • Case 1 : Yes conventional loop is much faster in this case as toArray has a bit overhead.

    • Case 2 : I don't know anything about it, my apologies.

    • Case 3 : IntStream is not slow at all, IntStream.range and conventional loop are almost same in terms of performance.

    See :

    • Java 8 nested loops with streams & performance
    0 讨论(0)
  • 2020-12-29 02:03

    You could implement your Mersenne Twister as an Iterator and stream from that.

    0 讨论(0)
  • 2020-12-29 02:08

    Basically, if you want Stream operations, you can use the range() method. For example, to use concurrency or want to use map() or reduce(). Then you are better off with IntStream.

    For example:

    IntStream.range(1, 5).parallel().forEach(i -> heavyOperation());
    

    Or:

    IntStream.range(1, 5).reduce(1, (x, y) -> x * y)  
    // > 24
    

    You can achieve the second example also with a for-loop, but you need intermediate variables etc.

    Also, if you want the first match for example, you can use findFirst() and cousins to stop consuming the rest of the Stream

    0 讨论(0)
  • 2020-12-29 02:09

    Here's an example:

    public class Test {
    
        public static void main(String[] args) {
            System.out.println(sum(LongStream.of(40,2))); // call A
            System.out.println(sum(LongStream.range(1,100_000_000))); //call B
        }
    
        public static long sum(LongStream in) {
            return in.sum();
        }
    
    }
    

    So, let's look at what sum() does: it counts the sum of an arbitrary stream of numbers. We call it in two different ways: once with an explicit list of numbers, and once with a range.

    If you only had call A, you might be tempted to put the two numbers into an array and pass it to sum() but that's clearly not an option with call B (you'd run out of memory). Likewise you could just pass the start and end for call B, but then you couldn't support the case of call A.

    So to sum it up, ranges are useful here because:

    • We need to pass them around between methods
    • The target method doesn't just work on ranges but any stream of numbers
    • But it only operates on individual numbers of the stream, reading them sequentially. (This is why shuffling with streams is a terrible idea in general.)

    There is also the readability argument: code using streams can be much more concise than loops, and thus more readable, but I wanted to show an example where a solution relying on IntStreans is functionally superior too.

    I used LongStream to emphasise the point, but the same goes for IntStream

    And yes, for simple summing this may look like a bit of an overkill, but consider for example reservoir sampling

    0 讨论(0)
  • 2020-12-29 02:12

    Here are few differences that comes to my head between IntStream.range and traditional for loops :

    • IntStream are lazily evaluated, the pipeline is traversed when calling a terminal operation. For loops evaluate at each iteration.
    • IntStream will provides you some functions that are commonly applied to a range of ints such as sum and avg.
    • IntStream will allow you to code multiple operation over a range of int in a functional way which read more fluently - specially if you have a lot of operations.

    So basically use IntStream when one or more of these differences are useful to you.

    But please bear in mind that shuffling a Stream sound quite strange as a Stream is not a data structure and therefore it does not really make sense to shuffle it (in case you were planning on building a special IntSupplier). Shuffle the result instead.

    As for the performance, while there may be a few overhead, you will still iterate N times in both case and should not really care more.

    0 讨论(0)
  • 2020-12-29 02:13

    IntStream.range returns a range of integers as a stream so you can do stream processing over it.

    like taking square of each element

    IntStream.range(1, 10).map(i -> i * i);  
    
    0 讨论(0)
提交回复
热议问题