目录
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(int index)
// 通过索引查找速度快
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);