LinkedList的add源码(2)
上一篇文章我们看了不指定下标的情况下java对LinkedList添加元素是如何处理的,这次我们就看下在指定下标的情况下又是如何实现元素的添加的呢?
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(2,4);
}
看看代码
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
下面这个方法是检查你要插入的位置是否在0到size之间,size就是当前链表的长度。
checkPositionIndex(index)
再继续往下看, if (index == size)
,说明刚好是要添加到链表的末尾,linkLast
方法我们上一篇已经看过了这里就不再看了。继续看node(index)
/**
* Returns the (non-null) Node at the specified element index.
*/
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;
}
}
这个方法很显然是获取原本位置在index的节点,而且我们可以看到,为了缩短运行时间,源码根据index是在链表的后半部分还是前半部分选择从前遍历还是从后遍历。
再看linkBefoe
方法
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
我们可以看到succ就是当前下标为index的元素,pred是succ的前一个元素,e就是要插入的元素,再新建一个node,该node指向succ和pred,但是此时pred.next还是succ,succ.prev还是pred,所以接下来就是把succ.prev指向newNode,然后把pred.next指向newNode,这样就插入成功了。