目录
ArrayList详解
ArrayList的注意事项
-
ArrayList 可以存放null,并且可以存放多个null
-
ArrayList 是由数组来实现数据存储的
-
ArrayList 中的方法没有用 sychronized 关键字修饰,所以线程不安全
-
ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全(执行效率高),因此在多线程情况下,不建议使用ArrayList
-
返回上次跳转的位置的快捷键:ctrl + alt + 方向键
-
格式化代码块:ctrl + alt + L
ArrayList 的底层操作机制源码分析
-
ArrayList 中维护了一个Object类型的数组elementData
-
transient Object[] elementData; // transient 表示瞬间,短暂的,表示该属性不会被序列化
-
-
当创建 ArrayList 对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容为elementData的1.5倍
-
如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容为elementData的1.5倍
分析使用无参构造器,创建和使用 ArrayList 的源码
public class Demo03 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
for (int i = 1; i <=10; i++) {
list.add(i);
}
for (int i = 11; i <=15; i++) {
list.add(i);
}
list.add(100);
list.add(200);
list.add(null);
}
}
-
1.执行 ArrayList list = new ArrayList();
-
创建了一个空的 elementData 数组
-
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
-
2.执行 List.add(E e)
-
ensureCapacityInternal(size + 1); , 先确定是否需要扩容
-
然后再执行赋值
-
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
-
3.执行ensureCapacityInternal(size + 1); ,该方法确定 minCapacity
-
第一次扩容为10
-
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
-
4.执行 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
-
modCount++; 记录集合被修改的次数,防止多线程的操作出现异常
-
如果 elementData 的大小不够,就调用 grow() 去扩容
-
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
-
5.执行 grow(minCapacity);
-
真的进行扩容
-
使用扩容机制来确定要扩容到多大
-
第一次 newCapacity = 10
-
第二次及其以后,newCapacity 按照1.5倍进行扩容
-
扩容使用的是 Arrays.copyOf()
-
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);
}
分析使用有参构造器,创建和使用 ArrayList 的源码
public class Demo03 {
public static void main(String[] args) {
ArrayList list = new ArrayList(8);
for (int i = 1; i <=10; i++) {
list.add(i);
}
for (int i = 11; i <=15; i++) {
list.add(i);
}
list.add(100);
list.add(200);
list.add(null);
}
}
-
1.执行 ArrayList list = new ArrayList(8);
-
创建了一个指定大小为 8 的elementData数组
-
this.elementData = new Object[initialCapacity];
-
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
使用有参构造器的扩容机制:
第一次扩容时,就按照elementData的1.5倍进行扩容,其余的流程和无参构造器一样