LinkedList 类的层次结构如下图所示:
-
LinkedList 是一个继承自 AbstractSequentialList 的双向链表,因此它也可以被当作堆栈、队列或双端队列进行操作。
-
LinkedList 实现了 List 接口,所以能对它进行队列操作。
-
LinkedList 实现了 Deque 接口,所以能将 LinkedList 当作双端队列使用。
明白了 LinkedList 的一些理论知识后,我们来看一下如何使用 LinkedList。
01、如何创建一个 LinkedList
LinkedList list = new LinkedList<>();
和创建 ArrayList 一样,可以通过上面的语句来创建一个字符串类型的 LinkedList(通过尖括号来限定 LinkedList 中元素的类型,如果尝试添加其他类型的元素,将会产生编译错误)。
不过,LinkedList 无法在创建的时候像 ArrayList 那样指定大小。
02、向 LinkedList 中添加一个元素
可以通过 add()
方法向 LinkedList 中添加一个元素:
LinkedList list = new LinkedList<>();
list.add(“沉默王二”);
list.add(“沉默王三”);
list.add(“沉默王四”);
感兴趣的小伙伴可以研究一下 add()
方法的源码,它在添加元素的时候会调用 linkLast()
方法。
void linkLast(E e) {
final LinkedList.Node l = last;
final LinkedList.Node newNode = new LinkedList.Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
添加第一个元素的时候,last 为 null,创建新的节点(next 和 prev 都为 null),然后再把新的节点赋值给 last 和 first;当添加第二个元素的时候,last 为第一个节点,创建新的节点(next 为 null,prev 为第一个节点),然后把 last 更新为新的节点,first 保持不变,第一个节点的 next 更新为第二个节点;以此类推。
还可以通过 addFirst()
方法将元素添加到第一位;addLast()
方法将元素添加到末尾;add(int index, E element)
方法将元素添加到指定的位置。
03、更新 LinkedList 中的元素
可以使用 set()
方法来更改 LinkedList 中的元素,需要提供下标和新元素。
list.set(0, “沉默王五”);
来看一下 set()
方法的源码:
public E set(int index, E element) {
checkElementIndex(index);
LinkedList.Node x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
该方法会先对指定的下标进行检查,看是否越界,然后根据下标查找节点:
LinkedList.Node node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
LinkedList.Node x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
LinkedList.Node x = last;
for (int i = size - 1; i > index; i–)
x = x.prev;
return x;
}
}
node()
方法会对下标进行一个初步的判断,如果靠近末端,则从最后开始遍历,这样能够节省不少遍历的时间,小伙伴们眼睛要睁大点了,这点要学。
找到节点后,再替换新值并返回旧值。
04、删除 LinkedList 中的元素
可以通过 remove()
方法删除指定位置上的元素:
list.remove(1);
该方法会调用 unlink()
方法对前后节点进行更新。
E unlink(LinkedList.Node x) {
// assert x != null;
final E element = x.item;
final LinkedList.Node next = x.next;
final LinkedList.Node prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size–;
modCount++;
return element;
}
还可以使用 removeFirst()
和 removeLast()
方法删除第一个节点和最后一个节点。
05、查找 LinkedList 中的元素
如果要正序查找一个元素,可以使用 indexOf()
方法;如果要倒序查找一个元素,可以使用 lastIndexOf()
方法。
来看一下 indexOf()
方法的源码:
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (LinkedList.Node x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (LinkedList.Node x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
Java高频面试专题合集解析:
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
更多Java架构进阶资料展示
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
etty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!**
[外链图片转存中…(img-MSD9IBTZ-1713740891650)]
更多Java架构进阶资料展示
[外链图片转存中…(img-fpmTyLru-1713740891650)]
[外链图片转存中…(img-aYLDPltd-1713740891651)]
[外链图片转存中…(img-8VIlf0th-1713740891651)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!