共计 1070 个字符,预计需要花费 3 分钟才能阅读完成。
双向链表结构
LinkedList 作为 java 又一大常用集合,其内部也有许多特性需要关注,首先我们从源码可以剖析出 LinkedList 为一个双向链表结构,如下图:
具体源码分析如下:
首先是 LinkedList 里的重要属性:
// 链表首指针
transient Node<E> first;
// 链表尾指针
transient Node<E> last;
LinkedList 的默认构造器为一个空构造器:
/**
* Constructs an empty list.
*/
public LinkedList() {}
下面来看看 linkedlist 的 add 方法:
public boolean add(E e) {linkLast(e);
return true;
}
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++;
}
//Node 为 LinkdList 的静态内部类
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
可以看出整个数据结构是以双向链表操作添加节点的。
linkedList 中还有一个重要的 get 方法,通过双向链表的特殊特性遍历节点时无需遍历全部节点即可找出所需节点:
public E get(int index) {checkElementIndex(index);
return node(index).item;
}
关注 node 方法里的算法:
Node<E> node(int index) {// assert isElementIndex(index);
// 判断传入的索引位置是否靠近最左端还是最右端
if (index < (size >> 1)) {
// 靠近左端则用首指针遍历
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
// 靠近右端则用尾指针遍历
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
正文完
发表至: java
2019-11-01