/**
* 考虑的比较的周全,并且包含了全部的情况,代码也不乱<b></b>
*
* @param index
* 插入的位置
* @param c
* 插入的元素集合
*/
private boolean addAll(int index, Collection<? extends E> c) {
// 缺少对于size的参数的校验
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
// 确定插入的位置和插入的前一个位置
Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index);
pred = succ.prev;
}
// 首先就是能够确认自己前面的一个节点是谁,size指的是插入的位置,后面的全部的一次
// 向后移动
for (Object o : a) {
@SuppressWarnings("unchecked")
E e = (E) o;
Node<E> newNode = new Node<E>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
// 把插入后面的元素接上
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
return true;
}
/**
* Returns the (non-null) Node at the specified element index. the alg is
* interesting
*/
private Node<E> node(int 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;
}
}
add function 代码写的还是比较的精彩的:
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* @param e
*/
private void linkLast(E e) {
// 尾节点,final ?
final Node<E> l = last;
final Node<E> newNode = new Node<E>(l, e, null);
last = newNode;
// special situation
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
}
/**
* Inserts the specified element at the specified position in this list.
* Shifts the element currently at that position (if any) and any subsequent
* elements to the right (adds one to their indices).
*
* @param index
* index at which the specified element is to be inserted
* @param element
* element to be inserted
* @throws IndexOutOfBoundsException
* {@inheritDoc}
*/
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
private void linkBefore(E element, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> insert = new Node<E>(pred, element, succ);
succ.prev = insert;
if (pred == null)
first = insert;
else
pred.next = insert;
size++;
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + size;
}