代码版本: JDK 1.8
- ArrayList实例化(为以下两种)
** 第1种:
/** * 无参构造函数。 创建一个长度为0的数组 此时并不会初始化容量 */
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
** 第2种:
/** 指定集合长度创建ArrayList 等于0和无参构造函数一样 */
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);
}
}
数组初始化之后,下一步就是增加元素了 !
- add方法
public boolean add(E e) {
// 判断数组容量情况 size+1是本次添加元素所需容量
ensureCapacityInternal(size + 1); // 👇下面进入此方法
elementData[size++] = e;
return true;
}
/** @param minCapacity 需要的最小容量 */
private void ensureCapacityInternal(int minCapacity) {
//返回需要容量 该方法就是比较个大小
int c = calculateCapacity(elementData, minCapacity);
// 扩容 👇下面进入此方法(下一代码块)
ensureExplicitCapacity(c);
/** ------------------ calculateCapacity()方法 -------------------------- ****
* private static int calculateCapacity(Object[] elementData, int minCapacity) {
* if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
* return Math.max(DEFAULT_CAPACITY, minCapacity);
* }
* return minCapacity;
* ------------------ ------------------ ------------------ ------------------ /
}
扩容逻辑在这里 👈👈
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 判断容量大小,如果容量大于数组长度 进入扩容逻辑
if (minCapacity - elementData.length > 0){
// 存储原始容量
int oldCapacity = elementData.length;
// 新容量扩容1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 扩容后的容量比需要的容量还小,就需要直接使用需要的容量扩容
if (newCapacity - minCapacity < 0)
// 新容量 = 需要的最小的容量
newCapacity = minCapacity;
// 扩容容量大于int最大值 使用int最大值
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 把原数组数据放入新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
add方法代码就这些
- 增加完了,开始查询。很简单,为了完整性,代码也贴出来。 ArrayList是基于数组实现的,所以查询速度很快,增删元素效率就比较低了(下次整理出来LinkedList)
public E get(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
return (E) elementData[index];
}
- 删除
public E remove(int index) {
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
// ★★ 代码就在这里一句话
System.arraycopy(elementData, index+1, elementData, index,numMoved);
//最后一个元素置空
elementData[--size] = null;
return oldValue;
}
解释下
System.arraycopy(src, srcPos, dest, destPos,length);
-
Object src : 原数组
-
int srcPos : 从元数据的起始位置开始
-
Object dest : 目标数组
-
int destPos : 目标数组的开始起始位置
-
int length : 要copy的数组的长度
大概意思是 从srcPos位置 拿length个数据,放在dest数组的destPos下标的位置,按拿的顺序排序放
src{0,1,2,3,4,5}
——> System.arraycopy(src, 3, dest, 2, 2);
dest {0,1,3,4,4,5}
- 修改(就是替换下)
public E set(int index, E element) {
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
- 按照指定位置增加元素
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
ensureCapacityInternal(size + 1); // 该方法上面有说明
// 这个在删除元素那里有 很简单
// 把index位置之后的所有数据下标➕1,然后index位置赋值为element
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
// 赋值
elementData[index] = element;
size++;
}
End!!! ArrayList还是很简单,那就从一个最简单的开始吧。如有不对的地方,欢迎指正。
第一次写文章,真的是挺费劲的。下次看看整理下LinkedList,