ArrayList特点:查询快、有序、自动扩容、元素可为空,源码解读从构造方法开始:ArrayList支持三种构造方式:
//初始化指定集合大小
public ArrayList(int var1) {
if (var1 > 0) {
this.elementData = new Object[var1];
} else {
//集合大小不能小于0
if (var1 != 0) {
throw new IllegalArgumentException("Illegal Capacity: " + var1);
}
this.elementData = EMPTY_ELEMENTDATA;
}
}
//不指定集合大小,默认为空数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//初始化指定某个集合,将形参集合传递给ArrayList的数组
public ArrayList(Collection<? extends E> var1) {
this.elementData = var1.toArray();
if ((this.size = this.elementData.length) != 0) {
if (this.elementData.getClass() != Object[].class) {
this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class);
}
} else {
this.elementData = EMPTY_ELEMENTDATA;
}
}
接着就是ArrayList常见的几个方法:获取集合大小、集合是否为空、是否包含某元素、转换为数组,都很简单:
public int size() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public boolean contains(Object var1) {
return this.indexOf(var1) >= 0;
}
public int indexOf(Object var1) {
int var2;
if (var1 == null) {
for(var2 = 0; var2 < this.size; ++var2) {
if (this.elementData[var2] == null) {
return var2;
}
}
} else {
for(var2 = 0; var2 < this.size; ++var2) {
if (var1.equals(this.elementData[var2])) {
return var2;
}
}
}
return -1;
}
public Object[] toArray() {
return Arrays.copyOf(this.elementData, this.size);
}
再接下来就是get获取元素方法了,get方法里面做了两个事情,先检查数组下标是否越界,越界直接抛异常,否则根据下标从数组中获取元素:
public E get(int var1) {
this.rangeCheck(var1);
return this.elementData(var1);
}
private void rangeCheck(int var1) {
if (var1 >= this.size) {
throw new IndexOutOfBoundsException(this.outOfBoundsMsg(var1));
}
}
接着是add方法,add方法里做了两个事:若为空数组,则初始化为大小为10,再确定数组的容量是否需要扩容,扩容为(原容量+原容量/2),接着在数组的(size+1)位置上放入新增的元素:
public boolean add(E var1) {
this.ensureCapacityInternal(this.size + 1);
this.elementData[this.size++] = var1;
return true;
}
private void ensureCapacityInternal(int var1) {
//注意空数组的特殊情况,将数组大小赋为10了
if (this.elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
var1 = Math.max(10, var1);
}
this.ensureExplicitCapacity(var1);
}
private void ensureExplicitCapacity(int var1) {
//modCount防止并发修改
++this.modCount;
//这个地方要注意:this.elementData在第一次add时候大小赋值为了10
if (var1 - this.elementData.length > 0) {
this.grow(var1);
}
}
private void grow(int var1) {
int var2 = this.elementData.length;
//扩容为(原容量+原容量/2)
int var3 = var2 + (var2 >> 1);
if (var3 - var1 < 0) {
var3 = var1;
}
if (var3 - 2147483639 > 0) {
var3 = hugeCapacity(var1);
}
this.elementData = Arrays.copyOf(this.elementData, var3);
}
private static int hugeCapacity(int var0) {
if (var0 < 0) {
throw new OutOfMemoryError();
} else {
return var0 > 2147483639 ? 2147483647 : 2147483639;
}
}
以上便是ArrayList的核心代码了,比较简单,如果别人面试时让你实现一个ArrayList,可千万别说不会,会被看扁的~
后面有空再补充一些吧~