1. 前言
众所周知,
LinkedList
是由链表实现的,其实它是由双向链表实现的。我们看一下源码中add,delete等是如何实现的。
2. LinkedList的属性
LinkedList
里只有一个int类型的长度size,和一个
Link
类型的voidLink。
Link
是内部类,其实相当于节点Node类。具体实现如下:
transient int size = 0; //长度
transient Link<E> voidLink; //结点voidLink
private static final class Link<ET> {
ET data; //数据域
//指向前一个结点的previous指针和指向后一个结点的next指针
Link<ET> previous, next;
Link(ET o, Link<ET> p, Link<ET> n) {
data = o;
previous = p;
next = n;
}
}
3. 构造函数
3.1 空构造函数
//默认前后指针都指向自己
public LinkedList() {
voidLink = new Link<E>(null, null, null);
voidLink.previous = voidLink;
voidLink.next = voidLink;
}
3.2 LinkedList(Collection collection)
public LinkedList(Collection<? extends E> collection) {
this();
//addAll的实现看下文
addAll(collection);
}
4. add方法
4.1 add(int location, E object)
双向链表插入一个数的思想如下:
- 定义一个临时指针link向后遍历,直到到达指定位置location(这里有个优化:如果location < size/2,则从前向后遍历,否则,从后向前遍历)
- new一个Link,数据域为要插入的object,previous指向link的previous,next指向link的next
-
size ++。
下图为双向链表中间插入的过程,头插和尾插这里不多说。
代码实现如下:java LinkedList源码解读1. 前言2. LinkedList的属性3. 构造函数4. add方法 @Override public void add(int location, E object) { if (location >= 0 && location <= size) { Link<E> link = voidLink; if (location < (size / 2)) { for (int i = 0; i <= location; i++) { link = link.next; } } else { for (int i = size; i > location; i--) { link = link.previous; } } Link<E> previous = link.previous; Link<E> newLink = new Link<E>(object, previous, link); previous.next = newLink; link.previous = newLink; size++; modCount++; } else { throw new IndexOutOfBoundsException(); } }