目录
1.ArrayList数据结构
2.主要参数
3.核心构造方法
3.1初始容量(10)
4. add(E e)方法
5.add(int index, E element)方法
6扩容机制
6.1 Arrays.copyOf(T[] original, int newLength)
7. get(intindex)
9.总结
1.ArrayList数据结构
private transient Object[] elementData;
|
可以看出ArrayList的数据结构为一个数组(查找速度快,使用索引的方式来快速定位对象的位置)
2.主要参数
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private transient Object[] elementData;
private int size;
|
3.核心构造方法
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
|
3.1初始容量(10)
可见初始化的时候可以指定ArrayList的容量,add方法会把容量最小设置为10(也算默认容量了);
4. add(E e)方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 设置初始容量大于等于10;
elementData[size++] = e; //添加元素在尾部
return true;
}
|
add(E e)方法直接将目标元素放置到数组末尾。
5.add(int index, E element)方法
public void add(int index, E element) {
rangeCheckForAdd(index); //索引大于数组长度抛异常IndexOutOfBoundsException
ensureCapacityInternal(size + 1); // 扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element; //可以插入索引和值
size++;
}
|
6扩容机制
由构造方法可知第一次创建数组的时候this.elementData = EMPTY_ELEMENTDATA;所以初始化容量最小为10;
以后每次添加新元素都会检查容量,容量不够扩大当前容量的50%
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity); }
|
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
//当容量不足才扩容 if (minCapacity - elementData.length > 0)
grow(minCapacity); //核心扩容方法 }
|
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//扩大原来容量的50% int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 扩大原来数组的长度Arrays.copyOf()分析如下 elementData = Arrays.copyOf(elementData, newCapacity);
}
|
6.1 Arrays.copyOf(T[] original, int newLength)
public static void main(String[] args) {
Object [] a;
a = new Object[]{1, 2, 3, 4, 5};
a = Arrays.copyOf(a, a.length<<1);
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
System.out.println();
}
|
输出
![]()
可以看出来数组的长度扩大了一倍
7. get(intindex)
//通过索引查找速度快
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
|
8. remove(Object o)方法
//需要遍历比较慢
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext()) {
if (it.next()==null) {
it.remove();
return true;
}
}
} else {
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
|
9.总结
1.ArrayList的数据结构是数组,所以具有数组的特性,根据索引查询速度快,添加元素直接添加在尾部也快,按照索引插入用的是System.arraycopy()方法,删除需要循环遍历比较慢。
2. ArrayList的数组初始长度为10,每次扩容扩大50%,扩大数组的方式用的是 Arrays.copyOf()方法
elementData = Arrays.copyOf(elementData, newCapacity);