美文网首页Android基础知识
使用ArrayList时设置初始容量的重要性

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

作者: 奇点一氪 | 来源:发表于2019-07-26 15:01 被阅读40次

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

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

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

    扩容代码如下:

    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

    相关文章

      网友评论

        本文标题:使用ArrayList时设置初始容量的重要性

        本文链接:https://www.haomeiwen.com/subject/gxfdrctx.html