JAVA---ArrayList,Verctor的底层源码CRUD分析
1.1 添加元素操作
JDK1.8源码
打断点DeBug,shift+alt+f7进入源码,然后看源码
//
object[] elementdate维护 size原数组元素个数,1为你需要的加入的一个元素
无参构造器 创建了空的elementdate 数组,有参构造器创建了指定大小的elementdate 数组
执行list.add();
1.先判断是否扩容
(1)先计算你数组内部容量:size+1, 然后赋值给最小容量minCapacity
(2)然后计算真正需要的最小容量minCapacity,先通过判断elementdate数组是否为空,
如果为空就就返回10和(内部容量或)传入的最小容量其中最大一个,并赋值给最小容量
从而得到真正所需的最小容量,如果不为空,就直接返回的最小容量即为真正所需的最小容量
(3)然后明确是真的否需要扩容:里面有modCount++;记录集合修改次数,防止多线程操
作出现异常;
然后将得到的最小容量和elementdate数组长度比较,如果前者大,就扩容,反之不扩容
2.扩容:先得到elementdate数组长度赋值给旧容量oldCapacity,然后扩大1.5
倍得
到新的容量newCapacity,{然后newCapacity和minCapacity,比较,前者大,就接着和数组
最大容量比较;【如果后者大就把minCapacity赋值为newCapacity,然后在和数组
最大容量比较】},如果小于最大容量,就通过Arrays.copyOf进行扩容,扩容大小为
新的容量大小,如果大于最大容量: Integer.MAX_VALUE -8, Integer.MAX_VALUE
赋值给newCapacity,通过Arrays.copyOf将就旧数组元素复制到新数组里
扩容大小为新的容量大小在指向elementdate
3.赋值
//
1.2删除元素操作
1.3 查找和修改元素操作
都是先判断索引是不是在数组索引的范围内,然后在的话直接通过索引获得对应的元素,修改的话,
就直接把该索引指向的重新赋值就行:elementData[index] = element;(这就是ArrayList查找和修改快的原因)
2.1
查找和修改以及删除元素操作和上面基本一样,但vector底层CRUD都是synchronized(线程同步)修饰的,所以他的效率都一般vector和arraylist就在扩容时有所不同,其他基本一样,可以看源码就知道。
打断点DeBug,shift+alt+f7进入源码
有参和无参几乎一样
集合长度length
Vector无参构造,如果创建的集合容量为空,就直接给你10个容量,然后走有参构造,然后走添加元素操作,里面有用modCount++;记录集合修改次数,
然后ensureCapacityHelper()方法判断是否需要扩容,你需要添加1个元素,需要的最小容量mincapacity就为元素个数加上添加的元素个数,然后mincapacity和length判断,
此时前面直接扩容了默认为10,mincapacity比length小,就不走grow()扩容,然后添加元素。
如果添加的元素超过了给定的默认值,或者自己设定的容器大小,就走grow()进行扩容,先获得oldcapacity也就是数组原来的大小,
然后三元运算符比较获得新的容量大大小newcapacity就为:oldcapacity+(capacityIncrement(增量,在有参构造器那写死的0)>0?capacity:oldcapacity)
扩容后依旧比需求小,就直接把所需容量mincapacity赋值给这个newcapacity
然后通过Arrays.copyOf对原数组进行扩容并赋值给原数组---//原数组=Arrays.copyOf(原数组,newcapacity)//----扩容为原来的两倍,然后赋值完成