# 属性

DEFAULT_CAPACITY 默认初始大小
EMPTY_ELEMENTDATA 空数组,申明了长度可能为0
DEFAULTCAPACITY_EMPTY_ELEMENTDATA 空数组 (无参构造时候的默认值)
elementData 承认数组元素
size 数组元素数量，注意和Lenth的

# 三种构造初始化

/**

*/
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);
}
}

/**
直接给一个默认的空数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

   public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();
if ((size = a.length) != 0) {
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}



## 分析

EMPTY_ELEMENTDATA是带参数的构建函数里长度为0的默认共享数组
DEFAULTCAPACITY_EMPTY_ELEMENTDATA是不带参数构造函数里长度为0的共享数组

    public boolean add(E e) {
//确保容量够不够，扩容机制
ensureCapacityInternal(size + 1);  // Increments modCount!!
elementData[size++] = e;
return true;
}

// step 1
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

// step 2. 计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) 	{
//判断是否是无参构造来的，为10个容量大小
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
//否则就给即将增长的长度
return minCapacity;
}

// step 3
private void ensureExplicitCapacity(int minCapacity) {
//修改次数
modCount++;

// 即将增长的长度比现的数组长度大就扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

// step 4
private void grow(int minCapacity) {
//原始长度
int oldCapacity = elementData.length;
//新长度 = 原始长度 + （原始长度/2)
int newCapacity = oldCapacity + (oldCapacity >> 1);

if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//尽量不扩容到 Intege 的最大值， 因为有些Vm的设计超过 MAX_ARRAY_SIZE 可能会 OOM错误 （OutOfMemoryError: Requested array size exceeds VM limit）
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);
}


## 分析

1. add函数，可以看出来，每次扩容都是本身的 0.5
2. 最大可以扩容到 Intege最大值，但也是在实际元素数量真的超过 MAX_ARRAY_SIZE的情况下。
3. 建立不超过MAX_ARRAY_SIZE的原因是 OutOfMemoryError: Requested array size exceeds VM limit
4. 为了避免开辟过多的数组空间，建立选择带参数的构造函数，以量申请。

# Remove方法

/**
*    第一个参数是要被复制的数组
*
* 　　第二个参数是被复制的数字开始复制的下标
*
* 　　第三个参数是目标数组，也就是要把数据放进来的数组
*
* 　　第四个参数是从目标数组第几个下标开始放入数据
*
* 　　第五个参数表示从被复制的数组中拿几个数值放到目标数组中
*/

public static native void arraycopy(Object src,  int  srcPos,
Object dest, int destPos,
int length);


elementData[--size] = null; // clear to let GC do its work


# 注意事项

1. 禁止在 forforeach里删除元素。
2. ArrayList在多线程环境中是不安全的
posted @ 2022-05-23 14:16  乌托拉赛文  阅读(152)  评论(0编辑  收藏  举报