ArrayList 源码查看
常量
DEFAULT_CAPACITY
/**
* 默认初始容量
*/
private static final int DEFAULT_CAPACITY = 10 ;
EMPTY_ELEMENTDATA
/**
* 用于空实例的共享空数组实例
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
/**
* 共享空数组实例用于默认大小的空实例
* 我们将此与EMPTY_ELEMENTDATA区分开来,以知道添加第一个元素时要增加多少。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: 请求的数组大小超过VM限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 ;
变量
elementData
/**
* 他存储ArrayList元素的数组缓冲区
* ArrayList的容量是这个数组缓冲区的长度.
* 当添加第一个元素时,任何具有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList将展开为DEFAULT_CAPACITY。
*/
transient Object[] elementData;
size
/**
* 代表ArrayList的长度
*/
private int size;
构造函数
ArrayList()
/**
* 构造一个初始容量为10的空集合
*/
public ArrayList () {
this .elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
ArrayList(int initialCapacity)
/**
* @description 用指定的初始容量构造一个空集合, 根据传入的参数 初始化一个空数组
* @param initialCapacity 集合的初始容量
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList (int initialCapacity) {
if (initialCapacity > 0 ) {
this .elementData = new Object[initialCapacity];
} else if (initialCapacity == 0 ) {
this .elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: " +
initialCapacity);
}
}
ArrayList(Collection< ? extends E > c)
/**
* 构造一个包含指定元素的列表
* 集合,它们按集合的迭代器返回的顺序排列。
*
* @param c 其元素将被放入此列表中的集合
* @throws NullPointerException if the specified collection is null
*/
public ArrayList (Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0 ) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
this .elementData = EMPTY_ELEMENTDATA;
}
}
方法
void trimToSize()
/**
* 将此ArrayList实例的容量修剪为列表的当前大小。
* 应用程序可以使用此操作来最小化ArrayList实例的存储。
*/
public void trimToSize () {
modCount++;
if (size < elementData.length) {
elementData = (size == 0 )
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
void ensureCapacity(int minCapacity)
/**
@ description 增加此数组列表实例的容量,如果必要,以确保它至少能容纳由最小容量参数指定的元素数目。
@ param minCapatity 期望的最小容量
**/
public void ensureCapacity (int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
void ensureCapacityInternal(int minCapacity)
/**
* 初始化数组使用 每次在增加元素的时候都会调用此方法
*/
private void ensureCapacityInternal (int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
void ensureExplcitCapacity(int minCapacity)
/**
* 在ensureCapacity 方法传入的长度 判断是否大于 现在数组的长度 如果大于就为数组增加空间
*/
private void ensureExplicitCapacity (int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0 )
grow(minCapacity);
}
void grow(int minCapacity)
/**
* 为数组动态分配空间 空间的分配的比例 数组的长度按移位运算增加 10 15 17 ....
*/
private void grow (int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1 );
if (newCapacity - minCapacity < 0 )
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0 )
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity (int minCapacity) {
if (minCapacity < 0 )
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
int size()
/**
* 返回元素集合的长度
*/
public int size () {
return size;
}
boolean isEmpty()
/**
* 如果集合中没有元素就返回true
*/
public boolean isEmpty () {
return size == 0 ;
}
boolean contains(Object o)
/**
* 如果集合包含指定的元素, 就返回true
* @param o 要在此列表中进行测试的元素
* @return 如果集合包含指定的元素, 就返回true
*/
public boolean contains (Object o) {
return indexOf(o) >= 0 ;
}
int indexOf(Object o)
/**
* 返回此列表中第一次出现指定元素的索引, 如果此列表不包含元素,则为-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 ;
}
int lastIndexOf(Object o)
/**
* 返回此列表中最后一次出现指定元素的索引 如果此列表不包含元素, 则为-1
*/
public int lastIndexOf (Object o) {
if (o == null ) {
for (int i = size-1 ; i >= 0 ; i--)
if (elementData[i]==null )
return i;
} else {
for (int i = size-1 ; i >= 0 ; i--)
if (o.equals(elementData[i]))
return i;
}
return -1 ;
}
Object clone()
/**
* 返回此ArrayList实例的浅表副本 (元素本身不被复制)
* @返回此ArrayList实例的克隆
*/
public Object clone () {
try {
ArrayList<?> v = (ArrayList<?>) super .clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0 ;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
Object toArray()
/**
* 返回包含所有的此集合中的元素的数组
* 按照正确的顺序(从第一个到最后一个元素)。
* 返回的数组将是“安全的”,因为此列表不会保留对它的引用 换句话说,这个方法必须分配一个新的数组
* 调用者可以自由修改返回的数组。
*/
public Object[] toArray () {
return Arrays.copyOf(elementData, size);
}
E get(int index)
/**
* 返回此列表中指定位置的元素。
* @param index 要返回元素的缩索引
* @return 集合中指定位置的元素
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get (int index) {
rangeCheck(index);
return elementData(index);
}
E set(int index, E element)
/**
* 用指定的元素, 替换指定位置上的元素
*
* @param index 要替换的元素的索引
* @param element 要在指定的位置上存储的元素
* @return 返回之前在指定位置上的元素
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set (int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
boolean add(E e)
/**
* 在列表的最后, 追加指定的元素
*
* @param e
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add (E e) {
ensureCapacityInternal(size + 1 );
elementData[size++] = e;
return true ;
}
void add(int index, E element)
/**
* 在集合的指定位置添加指定的元素. 将当前位置的元素和后续的元素移动到右侧
*/
public void add (int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1 );
System.arraycopy(elementData, index, elementData, index + 1 ,
size - index);
elementData[index] = element;
size++;
}
E remove(int index)
/**
* 移除在指定位置上的元素.
* 在他右边的元素 都向左移.
* @return 被删除的元素
*/
public E remove (int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1 ;
if (numMoved > 0 )
System.arraycopy(elementData, index+1 , elementData, index,
numMoved);
elementData[--size] = null ;
return oldValue;
}
boolean remove(Object o)
/**
* 从该列表中删除指定元素的第一个匹配项(如果存在)
* 如果该列表不包含该元素,则不变.
* 大多数情况下,删除索引最小的元素
*/
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 ;
}
void clear()
/**
* 删除数组中所有的元素
*/
public void clear () {
modCount++;
for (int i = 0 ; i < size; i++)
elementData[i] = null ;
size = 0 ;
}
boolean addAll(Collection
/**
* 将指定集合中的所有元素按指定集合的Iterator返回的顺序附加到此列表的末尾。
* 如果在操作过程中修改了指定的集合,则此操作的行为未定义,这意味着如果指定的集合是这个列表
* 这个调用的行为是未定义的,并且这个列表是非空的
*/
public boolean addAll (Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew);
System.arraycopy(a, 0 , elementData, size, numNew);
size += numNew;
return numNew != 0 ;
}
public static void (Object src, int srcPos, Object dest, int destPos, int length)
src:源数组;
srcPos:源数组要复制的起始位置;
dest:目的数组;
destPos:目的数组放置的起始位置;
length:复制的长度。
boolean addAll(int index, Collection
/**
* 将指定集合中的所有元素插入此列表,从指定的位置开始
* 将当前在该位置的元素(如果有的话)和任何随后的元素移到右侧(增加它们的索引).
* 新元素将按照它们由指定集合的迭代器返回的顺序出现在列表中。
*/
public boolean addAll (int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew);
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 ;
}
私有方法
rangeCheck
/**
* 检查给定索引是否在范围内. 如果不存在就抛出异常.
*/
private void rangeCheck (int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
rangeCheckForAdd
/**
* 判断索引是否超过了数组的长度 或者小于0 主要用于在指定位置增加元素的判断
*/
private void rangeCheckForAdd (int index) {
if (index > size || index < 0 )
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
void fastRemove(int index)
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 ;
}
原文地址 http://www.atom.kim/blog/article/182