目录
数据结构有时候理解起来没问题,实现起来却很困难。下面在Java 的集合框架中学习如何构建双向链表
Java 的集合框架中,LinkedList 是基于双向链表结构的一种数据存储类,具有查询慢、增删快的特点,下面学习它的底层源码实现
首先格局打开
public class test01 {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("你好");
linkedList.add("中国");
linkedList.add("我爱你");
System.out.println(linkedList);
}
}
结构
在看源码之前,先熟悉一下 LinkedList 的内部结构
其中,Node 是它的静态内部类,是实现双向链表结构的一个重要的部分,可以称之为 节点
private static class Node<E> {
E item; //节点值:value
Node<E> next; //下一个节点的地址
Node<E> prev; //上一个节点的地址
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
size就是指的链表长度
源码部分
初始化创建 LinkedList 实例对象时两个Node属性的值都为null,接着调用 add() 方法添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
linkLast()
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
如图:
当添加第一个元素时,它既是头节点又是尾结点,只需要创建出来这个对象并把头尾节点的指针指向它所在的地址值即可。
当添加第二个元素开始,就需要走if分支的语句了。此时局部变量 l 不再为null,所以我们要在创建新元素的同时将新元素的prev属性指针指向前面的那一个元素,同时将尾节点的指针指向新元素,而前一个元素的next属性指针指向新元素,至此构建完毕。
完整流程:
- 将尾节点放在局部变量l 中;
final Node<E> l = last;
- 创建新节点,并将自身的 prev 属性指向前一个节点(这里因为每一次添加元素都会将尾节点指针指向新元素,所以再次添加新元素需要设置prev属性,只需要拿到当前尾节点的元素即可);
final Node<E> newNode = new Node<>(l, e, null);
- 将尾节点指针指向新节点;
last = newNode;
- 拿到前一个节点的 next 属性,并指向新节点
if (l == null) first = newNode; else l.next = newNode;