如何高效初始化含整数范围的ArrayList,避免循环实现?
嘿,这个需求我太熟悉了!当初我也不想写那种“重复又无聊”的循环,试过Stream之后也觉得有点“杀鸡用牛刀”的感觉,后来摸索出几个更高效的方案,分享给你:
1. 极致性能首选:预分配容量的手动循环
别小看循环,只要预先给ArrayList指定初始容量,就能避免内部数组的多次扩容开销,性能反而比很多“花里胡哨”的方法更优。代码其实也没多复杂:
int vertexCount = instance.getNumVertices(); ArrayList<Integer> numbers = new ArrayList<>(vertexCount); for (int i = 0; i < vertexCount; i++) { numbers.add(i); }
这个方案的核心是提前告诉ArrayList要存多少元素,它会直接分配足够的内存,不用在add元素时反复扩容,加上原生int循环的直接性,性能几乎是天花板级别。
2. 简洁兼顾性能:指定容量的Stream方案
如果你实在不想写循环,那可以优化你提到的IntStream用法——默认的Collectors.toList()不会预先分配容量,这才是导致你觉得“不划算”的关键。只要在collect的时候指定一个预分配容量的ArrayList,就能把开销降下来:
int vertexCount = instance.getNumVertices(); ArrayList<Integer> numbers = IntStream.rangeClosed(0, vertexCount - 1) .boxed() .collect(Collectors.toCollection(() -> new ArrayList<>(vertexCount)));
这里用toCollection()直接初始化一个带容量的ArrayList,避免了默认toList()的扩容开销,同时保留了Stream的简洁性,性能和手动循环差距很小。
3. 第三方工具类(可选)
如果你的项目已经引入了Guava,那可以用它的工具类一行搞定,底层也是优化过的实现:
int vertexCount = instance.getNumVertices(); ArrayList<Integer> numbers = Lists.newArrayList(Ints.range(0, vertexCount));
不过这个方案依赖第三方库,适合已经用Guava的项目,没必要为了这个需求单独引入。
小总结
- 追求最快速度:选预分配容量的手动循环;
- 想要代码简洁又不想牺牲太多性能:选指定容量的Stream方案;
- 已有Guava依赖:直接用工具类。
内容的提问来源于stack exchange,提问作者scd
相关产品推荐
相关产品推荐

