1, ArrayList 无参构造 默认有开辟10空间
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
2,add添加元素的分析有两个接口
①尾巴添加
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
分析ensureCapacityInternal()函数的接口
判断是否要内存扩大 如果扩大就调用grow()函数
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//扩大一半 空间
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果空间扩展最大值了 0x7fffffff 赋值大值
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);
}
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
在下面分析arraycopy拷贝的算法
②指定位置插入
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
ensureCapacityInternal(size + 1); // Increments modCount!!
//中间插入节点
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
拷贝数据判断是否32 的判
ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD
if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
// Copy char by char for shorter arrays.
//运算符优先级的操作 + , < ,==, &&
//判断是否是中间插入的算法
if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
// Copy backward (to avoid overwriting elements before
// they are copied in case of an overlap on the same
// array.)
//index 索引的后面拷贝
for (int i = length - 1; i >= 0; --i) {
dst[dstPos + i] = src[srcPos + i];
}
} else { //索引的前面拷贝
// Copy forward.
for (int i = 0; i < length; ++i) {
dst[dstPos + i] = src[srcPos + i];
}
}
} else {
// Call the native version for longer arrays.
arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
}
![这里写图片描述](http://img.blog.csdn.net/20171110232039221?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUG9pc3g=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
###3,remove元素的操作 两个接口同上
①,指定元素删除
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index); //指定下标删除元素 gc
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
fastRemove调用 System.arraycopy(elementData, index+1, elementData, index,
numMoved);方法
②,指定下标删除
中间调用 System.arraycopy(elementData, index+1, elementData, index,
numMoved);方法
3,get和set方法都是先判断下标是否越界 ,直接操作数组的
4,clear方法数组置空的操作
5,addAll方法的操作
①,尾巴添加
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
//添加数据的实际数据的空间
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
②,指定位置插入
public boolean addAll(int index, Collection<? extends E> c) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
和上面一样的操作