Java集合类随手记——ArrayList

来源:互联网 发布:淘宝店铺市场 编辑:程序博客网 时间:2024/06/07 07:20

一、关于remove

  • 如果是remove(int index) 会先调用
private void rangeCheck(int index) {  if (index >= size)   throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}

这里有我们熟悉的IndexOutOfBoundsException数组越界异常;

  • 如果是remove(Object o) 会转化成数组下标调用
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 }

最终调用System.arraycopy,以移动后续数据覆盖之前数据的方式实现删除。

二、关于保存数据的实体

transient Object[] elementData;

之所以定义成transient是因为,elementData默认初始化长度是10(DEFAULT_CAPACITY),当实际长度不足容量时,比如2,则后8个没存实际数据的位置是不会被序列化的。

三、关于forEach遍历时

  • 实际上for( : ) 是先会调用内部类Itr的hasNext判断是否有下个元素,
    之后调用next()取值给for中的变量。
  • 这里要注意,在next时会调用
final void checkForComodification() {  if (modCount != expectedModCount)     throw new ConcurrentModificationException();}

其中modCount每次对数组操作都会++,记录操作次数。
而在迭代器遍历的过程中,一旦发现这个对象的mcount和迭代器中存储的mcount不一样那就抛异常。
这就是为什么我们循环遍历中第二次调用remove等操作会异常的原因。
Fail-Fast 机制在ArrayList,LinkedList,HashMap中都会看到。

  • modCount是定义在父类AbstractList.java中
protected transient int modCount = 0;

而expectenModCount定义在私有内部类(迭代器的实现)Itr中

int expectedModCount = modCount;
原创粉丝点击