如何在Java中生成连续整数的列表或数组? [英] How can I generate a list or array of sequential integers in Java?

查看:1703
本文介绍了如何在Java中生成连续整数的列表或数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有简短而又甜蜜的方式来生成列表<整数> ,或者可能是整数[] int [] ,从某些开始值到结束 value?



也就是说,短于,但相当于 1 以下内容:

  void List< Integer> makeSequence(int begin,int end){
List< Integer> ret = new ArrayList<>(end - begin + 1);
for(int i = begin; i< = end; i ++){
ret.add(i);
}
返回ret;
}

使用番石榴是好的。



更新:



效果分析



自此问题起我已经收到了几个很好的答案,都使用原生Java 8和第三方库,我想我会测试所有解决方案的性能。



第一个测试只是测试创建使用以下方法的10个元素 [1..10] 的列表:




  • classicArrayList :我在问题中给出的代码(与adarshr的答案基本相同)。

  • eclipseCollections :给出的代码在下面的



    ...和长度= 10,000:





    对许多元素进行的长时间迭代使得事情变得非常平凡,但即使在10,000元素测试中,eclipse和番石榴的速度仍然快了两倍。



    因此,如果你真的想要一个 List< Integer> ,eclipse集合似乎是最好的选择 - 当然如果你在更多的地方使用流本机方式(例如,忘记 .boxed()并在原始域中进行减少),您可能最终会比所有这些变体更快。






    1 也许除错误处理外,例如,如果结束< 开始,或者大小超过某些实现或JVM限制(例如,大于 2 ^ 31-1 的数组。

    解决方案

    使用Java 8它非常简单,因此它甚至不再需要单独的方法:

      List< Integer> range = IntStream.rangeClosed(start,end)
    .boxed()。collect(Collectors.toList());


    Is there a short and sweet way to generate a List<Integer>, or perhaps an Integer[] or int[], with sequential values from some start value to an end value?

    That is, something shorter than, but equivalent to1 the following:

    void List<Integer> makeSequence(int begin, int end) {
      List<Integer> ret = new ArrayList<>(end - begin + 1);
      for (int i=begin; i<=end; i++) {
        ret.add(i);
      }
      return ret;  
    }
    

    The use of guava is fine.

    Update:

    Performance Analysis

    Since this question has received several good answers, both using native Java 8 and third party libraries, I thought I'd test the performance of all the solutions.

    The first test simply tests creating a list of 10 elements [1..10] using the following methods:

    • classicArrayList: the code given above in my question (and essentially the same as adarshr's answer).
    • eclipseCollections: the code given in Donald's answer below using Eclipse Collections 8.0.
    • guavaRange: the code given in daveb's answer below. Technically, this doesn't create a List<Integer> but rather a ContiguousSet<Integer> - but since it implements Iterable<Integer> in-order, it mostly works for my purposes.
    • intStreamRange: the code given in Vladimir's answer below, which uses IntStream.rangeClosed() - which was introduced in Java 8.
    • streamIterate: the code given in Catalin's answer below which also uses IntStream functionality introduced in Java 8.

    Here are the results in kilo-operations per second (higher numbers are better), for all the above with lists of size 10:

    ... and again for lists of size 10,000:

    That last chart is correct - the solutions other than Eclipse and Guava are too slow to even get a single pixel bar! The fast solutions are 10,000 to 20,000 times faster than the rest.

    What's going on here, of course, is that the guava and eclipse solutions don't actually materialize any kind of 10,000 element list - they are simply fixed-size wrappers around the start and endpoints. Each element is created as needed during iteration. Since we don't actually iterate in this test, the cost is deferred. All of the other solutions actually materialize the full list in memory and pay a heavy price in a creation-only benchmark.

    Let's do something a bit more realistic and also iterate over all the integers, summing them. So in the case of the IntStream.rangeClosed variant, the benchmark looks like:

    @Benchmark
    public int intStreamRange() {
        List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList());  
    
        int total = 0;
        for (int i : ret) {
            total += i;
        }
        return total;  
    }
    

    Here, the pictures changes a lot, although the non-materializing solutions are still the fastest. Here's length=10:

    ... and length = 10,000:

    The long iteration over many elements evens things up a lot, but eclipse and guava remain more than twice as fast even on the 10,000 element test.

    So if you really want a List<Integer>, eclipse collections seems like the best choice - but of course if you use streams in a more native way (e.g., forgetting .boxed() and doing a reduction in the primitive domain) you'll probably end up faster than all these variants.


    1 Perhaps with the exception of error handling, e.g., if end < begin, or if the size exceeds some implementation or JVM limits (e.g., arrays larger than 2^31-1.

    解决方案

    With Java 8 it is so simple so it doesn't even need separate method anymore:

    List<Integer> range = IntStream.rangeClosed(start, end)
        .boxed().collect(Collectors.toList());
    

    这篇关于如何在Java中生成连续整数的列表或数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆