1.ArrayList源码解析
1.1构造方法
- 通常使用的是无参的构造函数,会为elementData创建为一个空的数组
- 这边的elementData则为ArrayList的底层数据结构为一个对象数组,只需对这个对象数组进行维护即可
1.2Add方法(扩容)
- size默认为0,新增一个元素则+1后判断是否需要进行扩容
1.2.1容量初始化(内层)
- 判断elementData是否为空,为空的话则初始化容量为10,不为空则返回传入的minCapacity
1.2.2容量初始化(外层)
- modCount记录每次动作,类似于新增、删除等动作都会++
- 随后判断是否需要扩容,若需要扩容则调用grow方法
- grow方法中,首先新增原有长度的一半(>>为右移,表示/2),随后再进行判断,若第一次0/2还是为0的情况,则将初始化的mincapacity也就是10赋值给新的长度,再判断是否大于最大值约21 亿,一般不会超,最后将原数组的元素以及计算的新长度进行覆盖即可
1.3Add方法(赋值)
- 将传入的对象进行赋值后,返回true
1.4Remove方法
- 判断删除的下标是否越界
- 随后记录modcount++(所有的新增和删除都会记录次数)
- 获取index为下标的值
- 判断当前为第几个元素,随后进行移动,若数组为:{“a1”,“a2”,“a3”,“a4”},删除了"a2",则需要将后面的两个元素向前移动,最后将最后一个元素进行删除
- 最后返回删除的元素
2.LinkedList源码解析
2.1构造方法
- 什么也没做
2.2Add方法
- add方法中调用linkLast进行尾插
- linkLast方法中
①首先获取到last节点也就是之前最后一个节点,
②将新的值插入链表中,头节点指向刚刚获取的last(上一个节点),尾节点指向null
③将这个新的节点赋值为last节点
④若为第一个元素,则将头节点指向当前节点,若不为一个元素,则将上一个节点的尾指针指向当前节点完成闭环
⑤随后将size(链表容量)和modcount(新增删除等动作记录)进行新增
2.3Remove方法
- remove方法首先判断当前的index是否合法
- unlink从链表中删除节点
①若当前节点为第一个节点,则将first节点指向当前节点的后一个节点,若不为第一个节点,将当前节点的前节点与后节点相连,并断开当前节点的前节点
②若当前节点为最后一个节点,则将last节点指向当前节点的上一个节点,若不为第一个节点,将当前节点的前节点与后节点相连,并断开当前节点的后节点
③将当前节点的值置为null,减去size(链表容量),新增modcount(新增删除等动作记录)
3.总结
- 由于上述讲解了ArrayList和LinkedList的底层应用
- 可以得知ArrayList底层维护是数组,由于有数组下标所以更偏向处理查询类的业务,对增删业务需要将数组内容整个进行移动所以效率偏低
- 而LinkedList底层由链表维护善于处理增删业务,只需将链表节点中的指向进行更改即可,别的节点不受影响,但查询效率偏低
嘿嘿~搞定