/** * Links e as first element. */ privatevoidlinkFirst(E e){ final Node<E> f = first; // 暂存链表 //① 头插法,新建节点时,节点的next节点直接指向链表头节点 final Node<E> newNode = new Node<>(null, e, f); first = newNode; // first指针指向newNode if (f == null) // 如果原头节点是空,说明此时newNode就是作为链表的第一个节点,显然last也是要指向它 last = newNode; else// 原头节点不为空,那么在前面①头插法后,那么newNode就可以作为原头节点前驱节点 f.prev = newNode; size++; modCount++; // 新增节点肯定属于链表结构变化 }
linkLast
1 2 3 4 5 6 7 8 9 10 11 12 13
// 尾插法 voidlinkLast(E e){ final Node<E> l = last; // 暂存尾节点 final Node<E> newNode = new Node<>(l, e, null); // 够建新节点,前驱节点指向尾部节点 last = newNode; // 原尾部指针更新,指向新的尾部节点 if (l == null) // 如果l为空,那么将first指针指向新增节点 first = newNode; else l.next = newNode; // 尾节点不为空时插入,原为节点的next指针当然要指向新增的节点 size++; modCount++; }
linkBefore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Inserts element e before non-null Node succ. */ // 在一个为非空的后继节点插入新节点 voidlinkBefore(E e, Node<E> succ){ // assert succ != null; final Node<E> pred = succ.prev; // 暂存后继节点的前节点 final Node<E> newNode = new Node<>(pred, e, succ);// p<=>e<=>succ succ.prev = newNode; // 后继节点的前驱指针指向新节点 if (pred == null) // 如果pred为空,说明此时succ其实first节点,那么在first节点前插入新节点,可知插入结束后,将first更新指向新节点 first = newNode; else pred.next = newNode; // 原pred.next是指向succ,现在指向newNode,而newNode的next指向succ size++; modCount++; }
/** * Unlinks non-null first node f. */ // 将非空头节点脱离链表 private E unlinkFirst(Node<E> f){ // assert f == first && f != null; final E element = f.item; final Node<E> next = f.next; // 暂存除去头节点之后的子链表 f.item = null; f.next = null; // help GC first = next; // 更新first指向next节点,也即此时next节就是头节点角色 if (next == null) // 如果next为空,说明处理f时,链表仅有一个头节点,删除后,last指针也要指向null last = null; else next.prev = null; // 若还未执行next.prev = null时,next.prev是指向原f节点,上面完成f节点删除后,next作为头节点角色,当然pred指针需要指向null size--; modCount++; return element; }
/** * Unlinks non-null last node l. */ // 将尾节点脱离链表 private E unlinkLast(Node<E> l){ // assert l == last && l != null; final E element = l.item; final Node<E> prev = l.prev; // 暂存last节点之前的子链 l.item = null; l.prev = null; // help GC,此时last节点脱离原链表 last = prev; // 将last指针更新指向prev节点 if (prev == null) // 如果pred节点为空,说明此时pred就是头节点 first = null; else prev.next = null; // 如果pred节点不为空,那么此时pred作为子链的最后一个节点,next指针自然要指向null size--; modCount++; return element; }
/** * Unlinks non-null node x. */ // 将一个非空节点x脱离链表 E unlink(Node<E> x){ // assert x != null; final E element = x.item; final Node<E> next = x.next; // 前子链<=>x<=>后子链 中的 x<=>后子链 final Node<E> prev = x.prev; // 前子链<=>x<=>后子链 中的 前子链<=>x
if (prev == null) { // 如果x的前驱节的为空,说明此时删除x就是删除头节点,那么删除节后,first更新指向为next节点,此时next节点作为新的头节点 first = next; } else { prev.next = next; // 将pred.next=>x=>next 改为pred.next => next x.prev = null; // 将x节点脱离前驱节点 }
if (next == null) { // pred<=>x->null 变为 pred->null,那么删除x后,last更新指向新的尾节点pred last = prev; } else { next.prev = prev; // 原来next的前驱指针是指向x,那么x删除后,next.pred指向x节点的前驱节点即可:pred.next <= next x.next = null; // 将x节点脱离后继节点 }
/** * Returns the first element in this list. * * @return the first element in this list * @throws NoSuchElementException if this list is empty */ // 如果是空链表调用getFirst()方法就会抛出NSEE异常 public E getFirst(){ final Node<E> f = first; // if (f == null) // 注意技巧:先取出节点,再判断节点是否为空 thrownew NoSuchElementException(); return f.item; }
removeFirst
1 2 3 4 5 6 7 8
//NoSuchElementException – if this list is empty //如果是空链表调用removeFirst直接抛出异常 public E removeFirst(){ final Node<E> f = first; // 先取出节点 if (f == null) // 说明是空链表 thrownew NoSuchElementException(); return unlinkFirst(f); // 非空链表情况下调用unlinkFirst将first节点脱离链表 }
removeLast同理
addFirst
addFirst内部调用linkFirst实现将e节点使用头插法插入链表
1 2 3 4 5 6 7 8
/** * Inserts the specified element at the beginning of this list. * * @param e the element to add */ publicvoidaddFirst(E e){ linkFirst(e); }
add
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * Appends the specified element to the end of this list. 默认使用尾插法插入节点 * * <p>This method is equivalent to {@link #addLast}. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */
/** * Removes the first occurrence of the specified element from this list, * if it is present. If this list does not contain the element, it is * unchanged. More formally, removes the element with the lowest index * {@code i} such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> * (if such an element exists). Returns {@code true} if this list * contained the specified element (or equivalently, if this list * changed as a result of the call). * * @param o element to be removed from this list, if present * @return {@code true} if this list contained the specified element */ // 分两种删除方法 publicbooleanremove(Object o){ if (o == null) { // 1、如果给定的对象为空,那么直接遍历链表,找出链表的item为null的节点x,并删除x节点 for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); returntrue; } } } else { // 2、如果给定的对象为空,那么就遍历链表节点的item和o.item相等的节点,并删除之 for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); returntrue; } } } // 找不到给定o,当然是返回false returnfalse; }
clear
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicvoidclear(){ // Clearing all of the links between nodes is "unnecessary", but: // - helps a generational GC if the discarded nodes inhabit // more than one generation // - is sure to free memory even if there is a reachable Iterator for (Node<E> x = first; x != null; ) { Node<E> next = x.next; // 先暂存除去x节点的子类,next显然为子链头节点 x.item = null; x.next = null; x.prev = null; // help GC x = next; // 将x指针更新指向next节点 } first = last = null; // 头尾指针也要置空 size = 0; // size肯定为0 modCount++; }
/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index){ checkElementIndex(index); return node(index).item; }
privatevoidcheckElementIndex(int index){ if (!isElementIndex(index)) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); }
/** * Tells if the argument is the index of an existing element. */ //索引是从0开始到size-1,注意:这里是检查已存在节点的索引 privatebooleanisElementIndex(int index){ return index >= 0 && index < size; }
/** * Tells if the argument is the index of a valid position for an * iterator or an add operation. */ // 为迭代器或者add操作判断给定索引是否有效位置 privatebooleanisPositionIndex(int index){ return index >= 0 && index <= size; }
indexOf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//Returns the index of the first occurrence of the specified element in this list, //从链表头节点位置开始遍历 publicintindexOf(Object o){ int index = 0; //从0开始计数 if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) // 如果first节点恰好为null,那么return的index就是0,因此头节点和索引0可对齐,那么其他节点和之后的索引也能对齐。 return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; }
indexOf是从头节点开始遍历链表,而lastIndexOf是从尾部节点方向遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicintlastIndexOf(Object o){ int index = 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--;// 这里为何先自减1呢? 因为链表的索引范围是0到size-1 if (o.equals(x.item))//假设尾节点恰好满足条件,那么返回的index就是size-1值,所以上面一行用index++的原因。 return index; } } return -1; }
/** * 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; //应对index=0的情况,此时无需进入for,直接返回x for (int i = 0; i < index; i++) //针对其他节点,注意是从0开始遍历,如果index=2,对应的节点位置是在第3个节点位置,因为x=first算是一次,接下来在for循环恰好可以遍历2次,总共三次。 x = x.next; return x; } else { //如果索引大于链表长度的一半,则从尾部节点开始遍历 Node<E> x = last; //从尾部节点开始,注意是从size-1开始,考察index=size-1时,则i>index不会满足,不进入for循环而直接返回尾节点 for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
add方法-添加对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/** * Appends the specified element to the end of this list. * * <p>This method is equivalent to {@link #addLast}. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ publicbooleanadd(E e){ linkLast(e); returntrue; }
/** * 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} */ publicvoidadd(int index, E element){ checkPositionIndex(index); // 这里的index可以取到size值:index>=0 && <=size if (index == size) // 如果index就是size大小,那么说明是要在尾部插入新元素 linkLast(element); else // 注意:在这里是将新元素添加到node(index)这个节点的前面 linkBefore(element, node(index)); // pred<-->ele<-->node(index) }
1 2 3 4
public E remove(int index){ checkElementIndex(index); // remove时的索引判断范围:index>=0&&index<size,如果取index<=size,那么=号就会造成越界 return unlink(node(index)); // nodex(index)找到index指向的节点,然后复用unlink方法完成删除节点 }
peek
记着:先取出头节点,然后判断是否为null在做出其他操作处理
1 2 3 4
public E peek(){ final Node<E> f = first; // return (f == null) ? null : f.item; }
模拟stack的方法
1 2 3 4 5 6 7
publicvoidpush(E e){ addFirst(e); }
public E pop(){ return removeFirst(); }
removeLastOccurrence
从尾部移除首次符合给定item的节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
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);// 找到这个节点后,用unlink删除之 returntrue; } } } returnfalse; }
toArray
创建一个size同大的数组,然后从链表中,一个个拷贝到这个空数组中
1 2 3 4 5 6 7 8
public Object[] toArray() { Object[] result = new Object[size]; int i = 0; // 当然是从0开始拷贝 for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; //如果有2个节点,那么此时i++=1,也即res[1]=第2个节点的item return result; }
public Iterator<E> descendingIterator(){ // 注意:公开方法是Iterator类型,不是ListIterator,因此在实例使用中使用Iterator<String> itr=list.descendingIterator() 创建反向迭代器 returnnew DescendingIterator(); }
/** * Adapter to provide descending iterators via ListItr.previous */ privateclassDescendingIteratorimplementsIterator<E> { privatefinal ListItr itr = new ListItr(size()); // 这里的index取的是size值,因此在next()方法调用previous()方法时,previous()方法内部的next是指向null的,因此DescendingIterator的next()方法首次是返回last节点。 publicbooleanhasNext(){ return itr.hasPrevious(); } public E next(){ return itr.previous(); } publicvoidremove(){ itr.remove(); } }
参考previous方法
1 2 3 4 5 6 7 8 9
public E previous(){ checkForComodification(); if (!hasPrevious()) thrownew NoSuchElementException(); //如果ListItr itr = new ListItr(size()) ,那么next指针是指向null,因此根据下面可知,当previous()调用时,next要被更新指向last lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; }