基本属性
默认初始大小为10。
/**
*默认初始大小.
*/
private static final int DEFAULT_CAPACITY = 10;`
这两个数组用来区别用那种构造器初始化list,无参构造器使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA,有参构造器使用EMPTY_ELEMENTDATA
/**
* 用于空实例的共享空数组实例。
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 用于默认大小的空实例的共享空数组实例。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
size数组拥有元素的个数,elementData数组。(elementData.length>=size)
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
检验在迭代过程中List对象是否被修改了,如果被修改了则抛出java.util.ConcurrentModificationException异常;
protected transient int modCount = 0;
构造器
无参构造器
把DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData
/**
* 构造一个初始容量为10的空列表。
* 此时只是给了一个空数组,当第一次使用add时容量扩大到10
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
指定初始大小的构造器:
/**
* 构造一个指定大小的列表
*/
public ArrayList(int initialCapacity) {
//判断参数是否大于0,大于零初始化一个参数大小的数组
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//如果参数等于0,把EMPTY_ELEMENTDATA赋值给elementData
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
参数为指定集合元素的列表的构造器
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public ArrayList(Collection<? extends E> c) {
//1.把集合转成数组
Object[] a = c.toArray();
//2.判断数组长度是否不为0
if ((size = a.length) != 0) {
//2.1 判断集合类型是否是Arraylist
if (c.getClass() == ArrayList.class) {
//如果集合是ArrayList类型,把集合赋值给elementData
elementData = a;
} else {
//如果不是ArrayList类型,用Arrays工具类的copyof()方法转换成
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {
// 把空数组EMPTY_ELEMENTDATA赋值给elementData
elementData = EMPTY_ELEMENTDATA;
}
}
主要方法
add方法:
/**
* 将指定的元素追加到此列表的末尾。
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* 保证列表大小足够(是否需要扩容)
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/**
* 计算容量大小
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//如果elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,取DEFAULT_CAPACITY和minCapacity的最大值。
//所以无参构造器构造的列表初始大小为0,第一次add操作时扩大到10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
//AbstracList中的变量,记录列表在结构上被修改的次数
modCount++;
// 判断是否需要扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 扩容,位操作,扩容大小为原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果扩容之后仍小于所需大小,就把minCapacity设置为列表的大小
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果扩容后过大,进行内存溢出判断
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
// 内存溢出判断
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
指定下标添加元素 add:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
addAll方法
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
get方法
//返回此列表中指定位置的元素。
public E get(int index) {
//校验下标是否越界
rangeCheck(index);
return elementData(index);
}
set方法
/**
* 将此列表中指定位置的元素替换为指定的元素。并返回被替换元素。
*/
public E set(int index, E element) {
校验下标是否越界
rangeCheck(index);
// 获取要被替换的元素
E oldValue = elementData(index);
// 为该位置元素重新赋值
elementData[index] = element;
return oldValue;
}
clear方法
/**
* 删除所有元素
*/
public void clear() {
//AbstracList中的变量,记录列表在结构上被修改的次数
modCount++;
// 把元素全部指向null,表明可以被GC回收
for (int i = 0; i < size; i++)
elementData[i] = null;
//列表大小设置成0
size = 0;
}
contains方法
/**
* 如果此列表包含指定的元素,则返回true
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o element whose presence in this list is to be tested
* @return <tt>true</tt> if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* 返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回-1。
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
remove方法
/**
* 删除此列表中指定位置的元素。将任何后续元素向左移动(从其索引中减去一个)。
*/
public E remove(int index) {
//校验索引合法性
rangeCheck(index);
//AbstracList中的变量,记录列表在结构上被修改的次数
modCount++;
//获取要删除的值
E oldValue = elementData(index);
int numMoved = size - index - 1;
//判断是否为末元素,不是就复制一个列表
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//如果是末元素,把它置为null即可,不需要复制列表
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
/**
* 从此列表中删除指定元素的第一个匹配项(如果存在)。如果列表不包含该元素,则该元素保持不变。
*/
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;
}
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
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; // clear to let GC do its work
}
Iterator和ListIterator的区别
-
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
-
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
-
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。