使用ArrayList时设置初始容量的重要性

简介: ArrayList是Java中比较常用的一个类,它是基于数组实现,非线程安全,可快速随机访问List中的元素。ArrayList具有动态扩容的机制,每次在添加元素时,都会判断容量是否够用,如果不够用,则需要扩容。

ArrayList是Java中比较常用的一个类,它是基于数组实现,非线程安全,可快速随机访问List中的元素。

ArrayList具有动态扩容的机制,每次在添加元素时,都会判断容量是否够用,如果不够用,则需要扩容。

JDK1.8中,ArrayList的初始容量为0,第一次添加元素时,会将容量设置为10,如果容量不够,则每次会扩大50%

扩容代码如下:

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

其中:

int newCapacity = oldCapacity + (oldCapacity >> 1);

容量被扩充为原容量的1.5倍,oldCapacity>>1,右移一位,即:oldCapacity除以2

elementData = Arrays.copyOf(elementData, newCapacity);

用Arrays的copyOf方法拷贝原数组内容,并设置新的长度。

可以看到ArrayList扩容需要做一次数组拷贝,如果是反复扩容,肯定会对程序的运行效率产生影响。所以在初始化ArrayList的时候,尽量设置初始化容量,避免其扩容。

测试代码:

        final int count = 20 * 100000;
        List<Integer> list = new ArrayList<>();
        long begin = System.currentTimeMillis();
        for(int i = 0; i < count ; i++) {
            list.add(i);
        }
        System.out.println("没有设置ArrayList初始容量: " + (System.currentTimeMillis() - begin) + " ms");
        
        list = new ArrayList<>(count);
        begin = System.currentTimeMillis();
        for(int i = 0; i < count ; i++) {
            list.add(i);
        }
        System.out.println("设置了ArrayList初始容量: " + (System.currentTimeMillis() - begin) + " ms");

执行结果:

没有设置ArrayList初始容量: 89 ms

设置了ArrayList初始容量: 18 ms

相关文章
|
7月前
|
存储 Java
ArrayList的初始化容量与扩容机制解析
ArrayList的初始化容量与扩容机制解析
|
7月前
|
算法
HashMap的默认初始长度是多少?为什么?
HashMap的默认初始长度是多少?为什么?
113 0
|
18天前
ArrayList自动扩充机制
ArrayList自动扩充机制 实现机制:ArrayList.ensureCapacity(int minCapacity) 首先得到当前elementData 属性的长度oldCapacity。 然后通过判断oldCapacity和minCapacity参数谁大来决定是否需要扩容, 如果minCapacity大于 oldCapacity,那么我们就对当前的List对象进行扩容。 扩容的的策略为:取(oldCapacity * 3)/2 + 1和minCapacity之间更大的那个。然后使用数组拷 贝的方法,把以前存放的数据转移到新的数组对象中 如果minCapacity不大于oldCapa
|
7月前
|
机器学习/深度学习 索引
认真研究HashMap的初始化和扩容机制
认真研究HashMap的初始化和扩容机制
208 0
toArray指定的容量和效率关系
toArray指定的容量和效率关系
57 0
|
存储 Java
深入理解ArrayList的动态扩容机制及应用
在java编程中,数据结构起着至关重要的作用,而ArrayList作为一种常用的动态数组,为我们在处理数据时提供了便利。其中,其独特的动态扩容机制更是为其赢得了广泛的应用。我们不管在工作还是面试中,都会遇到ArrayList,本文将深入探讨ArrayList的动态扩容机制,以便我们在工作或者面试中用到。
185 0
深入理解ArrayList的动态扩容机制及应用
|
Java
4.1 Java数组性能优化策略:合理选择数组大小与容量
4.1 Java数组性能优化策略:合理选择数组大小与容量
195 0
|
存储 Java
HasMap初始容量设置
HasMap初始容量设置
103 0
|
消息中间件 Java Kafka
【面试题看源码】-HashMap 初始容量 计算方法
【面试题看源码】-HashMap 初始容量 计算方法
【面试题看源码】-HashMap 初始容量 计算方法
System.ArgumentOutOfRangeException: 容量超出了最大容量
System.ArgumentOutOfRangeException: 容量超出了最大容量
259 0
System.ArgumentOutOfRangeException: 容量超出了最大容量