publicbooleanremove(Object o) { if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); returntrue; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); returntrue; } } } returnfalse; }
E unlink(Node<E> x) { // assert x != null; finalEelement= x.item; final Node<E> next = x.next; final Node<E> prev = x.prev;
if (prev == null) {// 第一个元素 first = next; } else { prev.next = next; x.prev = null; }
if (next == null) {// 最后一个元素 last = prev; } else { next.prev = prev; x.next = null; }
voidlinkLast(E e) { final Node<E> l = last; final Node<E> newNode = newNode<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
add(int index, E element), 当index==size时,等同于add(E e); 如果不是,则分两步: 1.先根据index找到要插入的位置,即node(index)方法;2.修改引用,完成插入操作。
publicbooleanaddAll(Collection<? extends E> c) { return addAll(size, c); }
publicbooleanaddAll(int index, Collection<? extends E> c) { checkPositionIndex(index);
Object[] a = c.toArray(); intnumNew= a.length; if (numNew == 0) returnfalse;
Node<E> pred, succ; if (index == size) { succ = null; pred = last; } else { succ = node(index); pred = succ.prev; }
for (Object o : a) { @SuppressWarnings("unchecked")Ee= (E) o; Node<E> newNode = newNode<>(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; modCount++; returntrue; }
clear()
为了让 GC 更快可以回收放置的元素,需要将node之间的引用关系赋空。
1 2 3 4 5 6 7 8 9 10 11 12 13
publicvoidclear() { for (Node<E> x = first; x != null; ) { Node<E> next = x.next; x.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; modCount++; }
Positional Access 方法
通过index获取元素
1 2 3 4 5
public E get(int index) { checkElementIndex(index); return node(index).item; }
将某个位置的元素重新赋值:
1 2 3 4 5 6 7 8
public E set(int index, E element) { checkElementIndex(index); Node<E> x = node(index); EoldVal= x.item; x.item = element; return oldVal; }
将元素插入到指定index位置:
1 2 3 4 5 6 7 8 9
publicvoidadd(int index, E element) { checkPositionIndex(index);
if (index == size) linkLast(element); else linkBefore(element, node(index)); }
删除指定位置的元素:
1 2 3 4
public E remove(int index) { checkElementIndex(index); return unlink(node(index)); }
privatevoidcheckElementIndex(int index) { if (!isElementIndex(index)) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); }
privatevoidcheckPositionIndex(int index) { if (!isPositionIndex(index)) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); }
查找操作
查找操作的本质是查找元素的下标:
查找第一次出现的index, 如果找不到返回-1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicintindexOf(Object o) { intindex=0; if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; }
查找最后一次出现的 index , 如果找不到返回-1;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicintlastIndexOf(Object o) { intindex= size; if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { index--; if (x.item == null) return index; } } else { for (Node<E> x = last; x != null; x = x.prev) { index--; if (o.equals(x.item)) return index; } } return -1; }
//删除列表中最后一次次出现的元素 publicbooleanremoveLastOccurrence(Object o) { if (o == null) { for (Node<E> x = last; x != null; x = x.prev) { if (x.item == null) { unlink(x); returntrue; } } } else { for (Node<E> x = last; x != null; x = x.prev) { if (o.equals(x.item)) { unlink(x); returntrue; } } } returnfalse; }