Java集合类随手记——ArrayList

一、关于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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 【传智播客.黑马程序员训练营成都中心】 转载请注明出处 作者:成都校区.堂堂老师 1. 什么时候会产生并发修改异常...
    OpenCoder阅读 1,539评论 0 3
  • ArrayList 源码分析 不知道各位朋友,还记得开工前制定的学习目标么? 有没有一直为了那个目标废寝忘食呢?继...
    醒着的码者阅读 1,524评论 6 11
  • 首先要感谢所有的亲朋好友~ 很早就预约了今年的北京之行,一生中非常重要的一次旅行。 一个新的家庭诞生了,小两口的结...
    无业遊民阅读 627评论 0 1
  • 文|勃然沧海 图|来自网络 不知怎么的,这部看似普通...
    勃然沧海阅读 329评论 0 1
  • 看到这个第一反应是这个 wifi改变了一代人的生活方式吗,后面还有几代暂且不说。全民手机时代,走哪哪第一件事是有w...
    LittlePiggie阅读 192评论 0 0

友情链接更多精彩内容