(八)JDK源码分析之集合框架ArrayList

  • 概述
    ArrayList是java集合框架中最常见的,也是用的最多的一种,底层采用的数据结构就是数组,使用和实现起来非常简单。

  • 构造方法
    在这里插入图片描述
    说明:构造方法一共三个
    1.直接指定一个初始大小,直接创建这个大小的数组分配给ArrayList持有,size=0
    2.无参构造函数,直接创建一个空数组分配给ArrayList持有,size=0
    3.使用符合有界泛型集合的持有数组分配给ArrayList持有,并且初始化size

  • 扩容策略
    在这里插入图片描述
    在这里插入图片描述
    说明:当需要添加元素的时候,为了确保空间够用,是需要扩容的,步骤如下:
    1.调用calculateCapacity计算最少需要的容量,第一次返回默认最少需要10,后面返回的代表的就是实际需要占用的数组元素个数
    2.调用ensureExplicitCapacity方法判断需不需要扩容,至少需要的容量和已经分配给ArrayList持有的容量比较,当实际需要容纳的数组元素个数大于分配给ArrayList持有的容量,那么需要扩容
    3.调用grow方法进行扩容,扩容的策略就是转为原来的容量的1.5倍(首次初始大小是0,直接分配10个空间),第一次10,第二次15…

  • 添加单个元素
    在这里插入图片描述
    说明:这里有两个添加单个元素方法:
    1.直接插入元素到最后,扩容+版本号+1,赋值到数组最后一个元素,时间复杂度O(1)
    2.插入元素到指定下标,检查数组有没有越界,扩容+版本号+1,下标之后元素进行整体向后移动,指定下标赋值新元素,时间复杂度O(n)

  • 删除单个元素
    在这里插入图片描述
    说明:有两个删除单个元素方法,一个指定下标删除,一个指定对象删除
    1.指定下标删除,检查下标合法性,版本号+1,计算移动数组元素数量,移动数组,将要被删除元素被覆盖,清空最后一个位置,元素真是数量size-1,时间复杂度O(n).
    2.删除指定元素对象,遍历数组,找到需要删除的对象,然后使用下标去做删除,后面流程就和1一样
    3.删除元素并没有改变ArrayList持有的数组的真正长度,只是清空了数据,然后真正有效数据大小size做了保存

  • 获取元素
    在这里插入图片描述
    在这里插入图片描述
    说明:直接返回指定下标的数组元素,时间复杂度O(1)

  • 集合的迭代器
    在这里插入图片描述
    说明:这里迭代器方法其实就是我们常用的hasNext和next方法
    1.hasNext用于判断是否还存在下一个元素,Itr类里面直接初始化了一个游标,游标初始化为0,直接和ArrayList持有的数组元素长度比较,就可以很简单判断有没有下一个元素
    2.next方法就直接返回下一个元素,首先会检查版本号,在获取迭代器那一刻起,这个版本号就定下来了,所以如果获取完迭代器后,对数组做了修改操作,那么这个迭代器在迭代过程中会抛出ConcurrentModificationException异常,因为你做了之后做了修改,这个迭代器很明显拿到的数据已经不是最新的,迭代出来的数据也是错误的,这个获取到的迭代器也就没意义了。
    在这里插入图片描述
    在这里插入图片描述
    说明:所以,如果想要对获得迭代器后,在迭代的同时做修改,必须使用迭代器的set,remove,add方法。那么为什么呢?其实这个是非常合理的,因为使用迭代器的方法去做修改操作,这样就通知了迭代器,迭代器就可以对读取的游标cursor做同步修改,这样就保证了迭代器读取数据的准确性

发布了65 篇原创文章 · 获赞 11 · 访问量 7137

猜你喜欢

转载自blog.csdn.net/weixin_38312719/article/details/103809582