ArrayList 源码阅读.
- // 测试代码实现如下
- private static void arrayList() {
- ArrayList<String> list = new ArrayList<String>();
- list.add("aaa");
- list.add("bbb");
- list.add("ccc");
- list.add("ddd");
- list.add("aaa");
- list.add("bbb");
- list.add("ccc");
- list.add("ddd");
- list.add("aaa");
- list.add("bbb");
- list.add("ccc");
- list.add("ddd");
- list.add(1, null);
- int size = list.size();
- for (int i = 0; i <size; i++) {
- System.out.println(list.get(i));
- }
- }
查看 ArrayList<String>(); 的源码的时候可以发现如下:
其属性 elementData 被初始化为一个空的 Object 数组.
- private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
- public ArrayList() {
- this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
- }
执行 list.add("aaa"); 可以看到如下源码:
其中的 size 表示目前 List 中已经存储的元素的数量, 目前为 0.
开始执行添加元素操作. add(e, elementData, size);
- protected transient int modCount = 0;
- transient Object[] elementData; // non-private to simplify nested class access
- private int size;
- public boolean add(E e) {
- modCount++;
- add(e, elementData, size);
- return true;
- }
进入 add(e, elementData, size); 可以看到如下源码:
已存储元素和当前的对象数组的长度相等, 都是 0.
执行数组扩容行动 elementData = grow();
当目前对象数组已满时得到, size==elementData.length.
进入 elementData = grow();, 继续扩容.
通过最后两行代码给对象数组赋值.
- private void add(E e, Object[] elementData, int s) {
- if (s == elementData.length)
- elementData = grow();
- elementData[s] = e;
- size = s + 1;
- }
进入 elementData = grow(); 可以看到如下源码:
grow() 函数 调用 grow(int minCapacity) 函数, 其中传参的值, 是目前需要的最小空间值.
在经过 newCapacity 的计算之后将 新的对象数组的值, copy 到 elementData 中. 由此便完成了第一次扩容.
最小值更新 minCapacity 为 11
- private Object[] grow(int minCapacity) {
- return elementData = Arrays.copyOf(elementData,
- newCapacity(minCapacity));
- }
- private Object[] grow() {
- return grow(size + 1);
- }
进入 newCapacity(minCapacity) 可以看到如下源码:
oldCapacity 旧容量的值设置为对象数组的长度, newCapacity 新容量的值设置为老容量 + 老容量的一次右移运算.
操作了半个小时结果发现 newCapacity 为 0, 然后进入 if 循环, 发现目前的 elementData 一点没动, 其地址还是最初的时候赋值的 DEFAULTCAPACITY_EMPTY_ELEMENTDATA.
在默认容量 DEFAULT_CAPACITY=10 和最小容量 minCapacity=1 之间选择一个最大值, 也就是 10. 作为返回值.
newCapacity 在经过右移运算后为 15 . 然后执行就以 15 为最新的扩容值为准 返回.
- private static final int DEFAULT_CAPACITY = 10;
- private int newCapacity(int minCapacity) {
- // overflow-conscious code
- int oldCapacity = elementData.length;
- int newCapacity = oldCapacity + (oldCapacity>> 1);
- if (newCapacity - minCapacity <= 0) {
- if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
- return Math.max(DEFAULT_CAPACITY, minCapacity);
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError();
- return minCapacity;
- }
- return (newCapacity - MAX_ARRAY_SIZE <= 0)
- ? newCapacity
- : hugeCapacity(minCapacity);
- }
总结: 其实就是扩容的操作解读, 赋值很简单. 而且源码的条例就是比我们自己写的好得多.
来源: https://www.cnblogs.com/A-FM/p/10970743.html