publicLinkedList(Collection<? extends E> c) { this(); addAll(c); }
通过调用addAll(int index, Collection<? extends E> c) 完成集合的添加。
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) { //新添加的元素的位置位于LinkedList最后一个元素的后面。 succ = null; pred = last; } else { //新添加的元素的位置位于LinkedList中。 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; }
privatevoidcheckPositionIndex(int index) { if (!isPositionIndex(index)) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); }
privatebooleanisPositionIndex(int index) { return index >= 0 && index <= size; }
辅助方法
把参数中的元素作为链表的第一个元素
因为我们需要把该元素设置为头节点,所以需要新建一个变量把头节点存储起来。
然后新建一个节点,把next指向f,然后自身设置为头结点。
再判断一下f是否为空,如果为空的话,说明原来的LinkedList为空,所以同时也需要把新节点设
置为尾节点。否则就把f的prev设置为newNode。
size和modCount自增。
privatevoidlinkFirst(E e) { final Node<E> f = first; final Node<E> newNode = newNode<>(null, e, f); first = newNode; if (f == null) last = newNode; else f.prev = newNode; size++; modCount++; }
把参数中的元素作为链表的最后一个元素
因为我们需要把该元素设置为尾节点,所以需要新建一个变量把尾节点存储起来。
然后新建一个节点,把last指向l,然后自身设置为尾结点。
再判断一下l是否为空,如果为空的话,说明原来的LinkedList为空,所以同时也需要把新节点设
置为头节点。否则就把l的next设置为newNode。
size和modCount自增。
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++; }
在非空节点succ之前插入元素e
首先我们需要新建一个变量指向succ节点的前一个节点,因为我们要在succ前面插入一个节点。
接着新建一个节点,它的prev设置为我们刚才新建的变量,后置节点设置为succ。
然后修改succ的prev为新节点。
接着判断一个succ的前一个节点是否为空,如果为空的话,需要把新节点设置为为头结点。
如果不为空,则把succ的前一个节点的next设置为新节点。
voidlinkBefore(E e, Node<E> succ) { // assert succ != null; final Node<E> pred = succ.prev; final Node<E> newNode = newNode<>(pred, e, succ); succ.prev = newNode; if (pred == null) first = newNode; else pred.next = newNode; size++; modCount++; }
private E unlinkFirst(Node<E> f) { // assert f == first && f != null; finalEelement= f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; }
删除LinkedList的最后一个节点
该节点不为空, 并且返回删除节点对应的值 。和unlinkFirst()方法思路差不多。
private E unlinkLast(Node<E> l) { // assert l == last && l != null; finalEelement= l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; }
删除一个节点(该节点不为空)
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; }
if (index < (size >> 1)) { Node<E> x = first; for (inti=0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (inti= size - 1; i > index; i--) x = x.prev; return x; } }
通用方法
可使用的删除头结点,并返回删除的值
public E removeFirst() { final Node<E> f = first; if (f == null) thrownewNoSuchElementException(); return unlinkFirst(f); }
删除链表中的最后一个节点,并返回被删除节点的值。
public E removeLast() { final Node<E> l = last; if (l == null) thrownewNoSuchElementException(); return unlinkLast(l); }
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; }
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.item = null; x.next = null; x.prev = null; x = next; } first = last = null; size = 0; modCount++; }
获取对应index的节点的值。
public E get(int index) { checkElementIndex(index); return node(index).item; }
设置对应index的节点的值
public E set(int index, E element) { checkElementIndex(index); Node<E> x = node(index); EoldVal= x.item; x.item = element; return oldVal; }
在指定的位置上添加新的元素
publicvoidadd(int index, E element) { checkPositionIndex(index);
if (index == size) linkLast(element); else linkBefore(element, node(index)); }
移除指定位置上的元素
public E remove(int index) { checkElementIndex(index); return unlink(node(index)); }
在LinkedList中查找object在LinkedList中最后出现的位置。
从后向前遍历,只返回第一出现的元素的索引,如果没找到,则返回-1
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; }
顺序遍历,只返回第一出现的元素的索引,如果没找到,则返回-1
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; }
实现双端队列的方法
返回头结点的值
//空直接返回 public E peek() { final Node<E> f = first; return (f == null) ? null : f.item; }
//空会抛出异常 public E element() { return getFirst(); }
移除头结点,并返回移除的头结点的值
//空直接返回 public E poll() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); }
//空抛出异常 public E remove() { return removeFirst(); } public E removeFirst() { final Node<E> f = first; if (f == null) thrownewNoSuchElementException(); return unlinkFirst(f); }
//弹出链表的头结点的元素,如果为空,则返回null public E peekFirst() { final Node<E> f = first; return (f == null) ? null : f.item; }
//弹出链表的尾结点的元素,如果为空,则返回null public E peekLast() { final Node<E> l = last; return (l == null) ? null : l.item; }
去除链表两端元素,并删除节点
//取出链表头节点的值,并删除该头节点。如果头结点为空,则返回null public E pollFirst() { final Node<E> f = first; return (f == null) ? null : unlinkFirst(f); } //取出链表尾节点的值,并删除该尾节点。如果头结点为空,则返回null public E pollLast() { final Node<E> l = last; return (l == null) ? null : unlinkLast(l); }
队列操作-增加、删除元素
//增加一个新的元素:(新添加的元素位于LinkedList的头结点。) publicvoidpush(E e) { addFirst(e); } //弹出头结点的元素。(删除头结点的值,并返回删除的值)(都是队列中才有的操作。) public E pop() { return removeFirst(); }
移除第一次或最后一次出现的元素。(遍历集合)
//从前向后 publicbooleanremoveFirstOccurrence(Object o) { return remove(o); } //从后向前 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; }
public Object clone() { LinkedList<E> clone = superClone();
// Put clone into "virgin" state clone.first = clone.last = null; clone.size = 0; clone.modCount = 0;
// Initialize clone with our elements for (Node<E> x = first; x != null; x = x.next) clone.add(x.item);
return clone; }
转化为数组
public Object[] toArray() { Object[] result = newObject[size]; inti=0; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; return result; }
* 泛型方法 * 在方法内部,如果a的长度小于集合的大小的话, * 通过反射创建一个和集合同样大小的数组, * 接着把集合中的所有元素添加到数组中。 * 如果数组的元素的个数大于集合中元素的个数,则把a[size]设置 * 为空。 * 我估计代码设计者这样设计代码的目的是为了能够通过返回值观察到 * LinkedList集合中原来的元素有哪些。通过null把集合中的元素凸显出来。 * ArrayList中也有同样的考虑和设计。 @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); inti=0; Object[] result = a; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item;
if (a.length > size) a[size] = null;
return a; }
序列化和反序列化
//将LinkedList写入到流中。(也就是把LinkedList状态保存到流中) privatevoidwriteObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject();
// Write out size s.writeInt(size);
// Write out all elements in the proper order. for (Node<E> x = first; x != null; x = x.next) s.writeObject(x.item); } //从流中把LinkedList读取出来(读取流,拼装成LinkedList)(反序列化) @SuppressWarnings("unchecked") privatevoidreadObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject();
// Read in size intsize= s.readInt();
// Read in all elements in the proper order. for (inti=0; i < size; i++) linkLast((E)s.readObject()); }
迭代器
//List的专有迭代器ListIterator。 public ListIterator<E> listIterator(int index) { checkPositionIndex(index); returnnewListItr(index); }
//向后遍历的Iterator public Iterator<E> descendingIterator() { returnnewDescendingIterator(); }