【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
ArrayList源码
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
......
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient E[] elementData;
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
......
}
ArrayList 的底层最重要的两个属性:Object 数组和 size 属性。
ArrayList 的底层数组的调整
add方法--ArrayList源码摘要:
public boolean add(E o) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = o;
return true;
}
ensureCapacity方法--ArrayList源码摘要:
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
}
elementData = (E[])new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
结论:
a. ArrayList 是通过将底层 Object 数组复制的方式(System.arraycopy方法)来处理数组的增长;
b. 当ArrayList 的容量不足时,其扩充容量的方式:先将容量扩充至当前容量的1.5倍,若还不够,则将容量扩充至当前需要的数量。
顺便看看 remove 方法
remove 方法--ArrayList源码摘要:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
fastRemove 方法--ArrayList源码摘要:
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; // Let gc do its work
}
private void fastRemove(int index) 可见,ArrayList 的元素移除后,也是通过 Object 数组复制的方式(System.arraycopy方法)来处理数组的变化; size 总是记录着当前的数组元素的数量。
这也就解释了 ArrayList 的特点:增加、删除和移动元素的效率低(数组复制过程消耗资源较多); 而查找元素和更新元素的效率高。
get 方法--ArrayList 源码摘要:
public E get(int index) {
RangeCheck(index);
return elementData[index];
}
set 方法--ArrayList 源码摘要:
public E set(int index, E element) {
RangeCheck(index);
E oldValue = elementData[index];
elementData[index] = element;
return oldValue;
}
来源:oschina
链接:https://my.oschina.net/u/1045974/blog/687668