LinkedList是双向链表,每个节点都可以找到下个节点和上个节点
代码中无论是查找,新增,删除以及各种变种(比如新增元素到第一个位置,新增到指定位置)之类的,都是根据first和last指针找到对应的位置,修改node节点的上/下个节点指针,达到目的
- 查找比较慢,因为要遍历,元素越多越慢
- 新增和删除节点很快,找到节点后改下指针就行
节点的代码实现:
item代表本节点该存储的值
next代表下个节点的指针
prev代表上个节点的指针
类中还有first和last用于指向头和尾指针
新增元素
新增单个元素
实际的实现代码在linkLast函数中
逻辑:
- last指针指向临时变量l
- 新增一个节点,新的节点的前一个节点是临时节点l(原本的last节点),下一个节点为null
- 当前节点给last指针(此处可以看出新增的节点一定是加到链表的最后)
- 如果原本的last是空的(本次调用是新增的第一个元素),当前节点给first指针。如果原本的last有值(原本列表中已经有元素了),将列表的原最后一个元素的下一个节点指向新增的节点
- 计数+1
如果有代码:
LinkedList<String> list = new LinkedList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
指定位置新增元素
如果位置是最后一个,直接调用在末节点新增节点,否则找到指定节点调用node(源码贴在下面)找到指定节点,在指定节点的前面新增元素
从下面两个函数看来,都是在指定节点中,修改first,last以及对应节点的next和pre来完成修改的
查找元素
根据下标查找
在node函数中根据索引下表查找元素,size>>1 右位移1等于总大小除以2,如果索引小于中间的索引,就从头first往后找,如果索引大于中间的索引,从尾last往前查,可以减少查询次数
根据内容查找
- 如果查找的是null,单独有个逻辑
- 如果查找的不是null,从first开始查,一直查到null结束,因为里面设计的最后一个有效元素的next一定是null,用equals看两个元素是否一样
不过如果有以下代码,查出来的索引位置是0,就是如果有多个一样的元素,找到最先插入的(源码注释中也有说明)
参考文章