//集合初始化的容量的默认大小
private static final int DEFAULT_CAPACITY = 10;

/**
* 用户指定为空的默认数组 和 DEFAULTCAPACITY_EMPTY_ELEMENTDATA进行一个区分
*/
private static final Object[] EMPTY_ELEMENTDATA = {};

/**
* 都是用来定义空的容量,这个是无参构造默认的空数组
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

/**
* 存储元素的数组缓存区,在添加第一个元素后扩容到默认的长度 DEFAULT_CAPACITY
*/
transient Object[] elementData; // non-private to simplify nested class access

/**
* 元素的大小,以实际的元素为准
*/
private int size;

 


//构造函数理解
/**
* 第一个构造,自定义集合的容量,如果说容量大于0,缓存数组初始化一个指定容量的Object数组
* 等于0 的时候直接赋值 EMPTY_ELEMENTDATA,和无参构造的DEFAULTCAPACITY_EMPTY_ELEMENTDATA作区分
* 输入小数直接抛出异常
*/
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);
}
}

/**
* 无参直接将缓存数组赋值DEFAULTCAPACITY_EMPTY_ELEMENTDATA,同上的EMPTY_ELEMENTDATA作区分
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

/**
* 添加一个集合,如果直接是空的话就赋值EMPTY_ELEMENTDATA,
* 如果不为空,判断当前的数组的的类型是否为Object[],不是的话需要在转换一次(装箱)
*
*
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}

 

/****************************************************************************************************
* **********************************添加元素到列表的尾部*********************************************
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#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) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}

private void ensureExplicitCapacity(int minCapacity) {
//记录值,修改的次数,迭代的时候会使用到
modCount++;

// 判断是否需要扩容,如果当前新增的长度超过了已有的长度
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

private void grow(int minCapacity) {
// 原始的值
int oldCapacity = elementData.length;
//新的扩容,1.5倍 例如 10扩容 1010 >>1 101 5 扩容成15
int newCapacity = oldCapacity + (oldCapacity >> 1);
//考虑是否有溢出,如果超出了init的最大值,oldCapacity >> 1是个负数
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新增的长度大于最大的容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// copy数组
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;
}
添加元素总结:
添加元素的时候内部主要的有一个扩容的机制,个人认为如果知道确定的size的话,初始化的时候可以直接指定大小,可以减少扩容的成本
/*************************************************************************************************************************/
/**********************************************************添加元素结束***************************************************/
/*************************************************************************************************************************/

 

/**
* ************************************************根据指标获取到元素******************************************************/
* ************************************************************************************************************************
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {

//进行一个范围的检查
rangeCheck(index);

return elementData(index);
}
// 如果查出了数组的范围,抛出异常
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/*****************************************************************************************************************************
***************************************************************获取元素******************************************************
*****************************************************************************************************************************/

 

/**
* 删除一个元素,并将后续的元素进行左移
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
//检查脚本范围
rangeCheck(index);

modCount++;
//获取到要删除的元素
E oldValue = elementData(index);

int numMoved = size - index - 1;
if (numMoved > 0)
/** String [] str=new String []{"1","2","3","4","5"};
* System.arraycopy(str, 2, str, 1,3);
* for (String string : str) {
* System.out.println(string);
* }
* 输出的结果为[1,3,4,5,5]
*
*/
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work

return oldValue;
}

 

 

/**
***************************************************************************************************************************
* *****************************************************集合迭代************************************************************
* Returns an iterator over the elements in this list in proper sequence.
*
* <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
*
* @return an iterator over the elements in this list in proper sequence
*/
public Iterator<E> iterator() {
return new Itr();
}


/**
* 这个对象就是list进行迭代操作
*/
private class Itr implements Iterator<E> {
//记录要读取的元素的脚标
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
//迭代的过程判断集合是否有修改
int expectedModCount = modCount;

public boolean hasNext() {
return cursor != size;
}
/**
* next方法主要确保角标的正确性,不能超出当前的长度,也不能少于当前的长度
*/
@SuppressWarnings("unchecked")
public E next() {
//判断迭代的过程中集合是否有修改 ,就是modcount这个数值记录List的每一次操作
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
/**
* 使用iterator迭代的时候,如果要使用remove,remove()放在 next()前后的效果是不一样的
* remove() 不能直接放到next()之前,throw new IllegalStateException(),如果加了条件判断,删除的也是当前角标的上一个元素
*
*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

总结:1、在使用list.iterator迭代的时候,如果去修改list的长度,都会在迭代的时候抛出异常,可以使用iterator.remove,因为重新设置了expectedModCount = modCount;这个方法使用的注意事项上边已经提到了,
2、同时使用iterator需要注意,iterator迭代完成后,内部的角标是指向末尾的,如果继续使用该对象迭代,是获取不要元素的,hasnext()返回的是false。