关于ArrayList$add(int index, E object)方法

画虎烂 发布于 2014/11/05 17:30
阅读 2K+
收藏 1
JDK

ArrayList有一个构造方法是带容量参数的

public ArrayList(int capacity) {
        if (capacity < 0) {
            throw new IllegalArgumentException("capacity < 0: " + capacity);
        }
        array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]);
    }



此时,我构建一个 ArrayList对象

ArrayList<String> lables=new ArrayList<String>(6);



根据以上的构造函数,那么这时array=new Object[6],它的容量应该是6,,那么当我调用 ArrayList$add(int index, E object)方法时,看如下源码:

public void add(int index, E object) {
        Object[] a = array;
        int s = size;
        if (index > s || index < 0) {
            throwIndexOutOfBoundsException(index, s);
        }

        if (s < a.length) {
            System.arraycopy(a, index, a, index + 1, s - index);
        } else {
            // assert s == a.length;
            Object[] newArray = new Object[newCapacity(s)];
            System.arraycopy(a, 0, newArray, 0, index);
            System.arraycopy(a, index, newArray, index + 1, s - index);
            array = a = newArray;
        }
        a[index] = object;
        size = s + 1;
        modCount++;
    }



IndexOutOfBoundsException的判断依据为什么不是根据array的大小来判断的,我们初始已经申请了容量大小6,理应应该是可以直接使用add(5,"test"),为什么这样设计


加载中
0
有明丶
有明丶

引用来自“有明丶”的评论

你看代码里已经很明确了,add的时候先比较了当前list的size,这个size是当前list内元素数量,不是arraylist的容量。

引用来自“画虎烂”的评论

以我们的角度来说,我们声明了arrayList的容量,是不是应该能操作容量内的数,为什么不是比较 array而是list的size

不是这么理解的,Capacity是为了更好的优化ArrayList的内存占用,而不是为了方便我们操作其中的元素而设计的。

ArrayList的内存申请有一定的盲目性,其原理是,一开始维系一个数组,当添加元素时发现数组已满,就新申请一个新数组,新数组的大小是原数组的两倍,然后把原数组拷贝到新数组里。

这样就出现一个问题,在某些时候可能会造成很大的内存浪费,比如当前ArrayList里有1024个元素,而内置数组也被填满了,这时候我们添加一个元素,那么新数组大小就是2048,而我们仅仅就只有1025个元素却占用了2048个单元的内存,这就是一种浪费了。而如果设置了Capacity,ArrayList申请新数组的时候会参考Capacity,避免内存的浪费。

0
画虎烂
画虎烂
没人知道吗
0
有明丶
有明丶
你看代码里已经很明确了,add的时候先比较了当前list的size,这个size是当前list内元素数量,不是arraylist的容量。
0
画虎烂
画虎烂

引用来自“有明丶”的评论

你看代码里已经很明确了,add的时候先比较了当前list的size,这个size是当前list内元素数量,不是arraylist的容量。
以我们的角度来说,我们声明了arrayList的容量,是不是应该能操作容量内的数,为什么不是比较 array而是list的size
0
石头哥哥
石头哥哥
list size 是当前元素个数(计数器) ,如果当前的元素超过了Array的length(这个就是你的capacity),就无法存储导致数据存储异常,list基于数组来存储元素,要保证数据被正确存储 且不越界。
返回顶部
顶部