JDK12下的ArrayList源码解读
2019-06-03 23:07
3019 查看
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); }
总结: 其实就是扩容的操作解读, 赋值很简单. 而且源码的条例就是比我们自己写的好得多.
相关文章推荐
- jdk 1.8 arraylist源码解读
- Java之ArrayList源码解读(JDK 1.8)
- jdk源码解读之ArrayList
- ArrayList 源码解读(JDK1.8)
- Java之ArrayList源码解读(JDK 1.8)
- JDK之ArrayList源码解读
- JDK之CopyOnWriteArrayList源码解读
- jdk1.8.0_45源码解读——ArrayList的实现
- java源码解读之ArrayList------jdk 1.7
- jdk1.8.0_73源码解读——ArrayList的实现
- jdk1.8.0_45源码解读——ArrayList的实现
- jdk源码解读-并发包-Lock-ReentrantLock(2)--await()与signal()方法走读
- 集合框架(一):ArrayList源码解读
- 【JDK1.8】JDK1.8集合源码阅读——ArrayList
- ArrayList源码解读
- JDK源码分析-ArrayList分析
- jdk源码阅读一:ArrayList
- ArrayList源码解读
- java源码解读之HashMap------jdk 1.7
- JAVA集合框架12---HashSet(JDK1.7)源码解析