LinkedList阅读

package java.util;import java.util.function.Consumer;public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{transient int size = 0;transient Node<E> first;transient Node<E> last;public LinkedList() {}// 传入一个Collection类型的集合,转换为linkedlist类型public LinkedList(Collection<? extends E> c) {this();addAll(c);}/*** 将一个element添加为第一个节点 该方法提供给addFirst调用*/private void linkFirst(E e) {//当前第一个节点暂存final Node<E> f = first;//新建一个节点,pre为空,next为之前的first节点final Node<E> newNode = new Node<>(null, e, f);//将当前节点设置为第一个节点,并且判断原来第一个节点是否存在,不存在,则新增节点既是first,也是last节点,//如果添加之前存在第一个节点,(因为linkedList是一个双向列表,所以需要将原第一个节点的pre设置为新增节点),添加完成之后size,modCount(改变次数)自增first = newNode;if (f == null)last = newNode;elsef.prev = newNode;size++;modCount++;}/*** 同linkFirst,将添加的节点设置为最后一个*/void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}/*** 在指定节点之前添加一个节点*/void linkBefore(E e, Node<E> succ) {// assert succ != null;//暂存指定节点的前一个节点final Node<E> pred = succ.prev;//创建新节点,且pre设置为pred,next设置为指定的节点(该新建只是指定了当前节点的pre和next,尚没有指定前一个节点的next和后一个节点的pre)final Node<E> newNode = new Node<>(pred, e, succ);//一下步骤是指定前一个节点的next和后一个节点的presucc.prev = newNode;if (pred == null)first = newNode;elsepred.next = newNode;size++;modCount++;}/*** 清掉第一个非空的节点.*/private E unlinkFirst(Node<E> f) {// assert f == first && f != null;//暂存要清掉节点的item和next,并将f节点的item和next置空(置空是为了帮助清理无用的空间)final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GC//将下一节点置为第一个节点(因是双向列表,所以需要设置节点的pre为空,同时size减小,modCount改变次数增加)first = next;if (next == null)last = null;elsenext.prev = null;size--;modCount++;//返回删除节点的itemreturn element;}/*** 同unlinkFirst方法,删除最后一个非空节点.*/private E unlinkLast(Node<E> l) {// assert l == last && l != null;final E element = l.item;final Node<E> prev = l.prev;l.item = null;l.prev = null; // help GClast = prev;if (prev == null)first = null;elseprev.next = null;size--;modCount++;return element;}/*** 删除指定节点.*/E unlink(Node<E> x) {// assert x != null;//暂存要删除节点的 值:item/next/prefinal E element = 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;}x.item = null;size--;modCount++;return element;}/*** 返回列表的第一个节点*/public E getFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return f.item;}/*** 返回节点的最后一个节点*/public E getLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return l.item;}/*** 删除第一个节点,(方法调用私有方法unlinkFirst)*/public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}/*** 删除最有一个节点*/public E removeLast() {final Node<E> l = last;if (l == null)throw new NoSuchElementException();return unlinkLast(l);}/*** 添加一个首节点*/public void addFirst(E e) {linkFirst(e);}/*** 添加尾节点** @param e the element to add*/public void addLast(E e) {linkLast(e);}/*** 判断列表中是否存在指定节点*/public boolean contains(Object o) {return indexOf(o) != -1;}/*** 列表大小*/public int size() {return size;}/*** 添加尾节点**/public boolean add(E e) {linkLast(e);return true;}/**删除链表中的指定值*/public boolean remove(Object o) {if (o == null) {//循环列表,将列表中null删除for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {//循环列表,删除列表中item为o的节点for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}return false;}/*** 构造函数调用,将一个collection类型的集合转换成一个linkedlist类型
*/public boolean addAll(Collection<? extends E> c) {return addAll(size, c);}/*** index:范围在【0-size】,当为0是,将集合中的节点添加的linkedlist的开头不为0是,则添加到第index位置*/public boolean addAll(int index, Collection<? extends E> c) {//校验index是否在[0,size]之间,不再则报错checkPositionIndex(index);Object[] a = c.toArray();int numNew = a.length;if (numNew == 0)return false;//index==size是 添加到最后Node<E> pred, succ;if (index == size) {succ = null;pred = last;} else {//暂存指定位置的节点,之后将该节点设置到新增集合节点中的后边succ = node(index);pred = succ.prev;}//循环设置新节点,并将pre的next设置为新增节点for (Object o : a) {@SuppressWarnings("unchecked") E e = (E) o;Node<E> newNode = new Node<>(pred, e, null);if (pred == null)first = newNode;elsepred.next = newNode;//为下一此循环判断,赋值 准备pred = newNode;}if (succ == null) {last = pred;} else {pred.next = succ;succ.prev = pred;}size += numNew;modCount++;return true;}/**清空链表*/public void clear() {// 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//节点全都置null,是为了方便释放内存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 Operations/*** 获取指定位置的节点值*/public E get(int index) {//判断index是否合法checkElementIndex(index);//node方法内部循环获取节点return node(index).item;}/*** 替换指定位置的节点,并返回旧节点的item*/public E set(int index, E element) {checkElementIndex(index);Node<E> x = node(index);E oldVal = x.item;x.item = element;return oldVal;}/**在指定位置添加节点*/public void add(int index, E element) {//校验位置是否合法checkPositionIndex(index);//index==size的话,表明指定的位置是在列表的最后if (index == size)linkLast(element);elselinkBefore(element, node(index));}/**删除指定位置的节点*/public E remove(int index) {checkElementIndex(index);return unlink(node(index));}/*** 判断指定位置是否存在一个节点(因为size表明链表的大小,只有index在[0,size]之间,表明指定index存在一个节点).*/private boolean isElementIndex(int index) {return index >= 0 && index < size;}/**判断指定位置是否合法(加入要新增节点,节点的位置只能在0-size之间,首尾位置也是可插入位置,合法)*/private boolean isPositionIndex(int index) {return index >= 0 && index <= size;}/*** Constructs an IndexOutOfBoundsException detail message.* Of the many possible refactorings of the error handling code,* this "outlining" performs best with both server and client VMs.*/private String outOfBoundsMsg(int index) {return "Index: "+index+", Size: "+size;}private void checkElementIndex(int index) {if (!isElementIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private void checkPositionIndex(int index) {if (!isPositionIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(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;}}// Search Operations/*** 返回指定对象在链表中第一次出现的位置,没有则返回-1*/public int indexOf(Object o) {int index = 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 int lastIndexOf(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--;if (o.equals(x.item))return index;}}return -1;}// Queue operations./*** 返回一个链表的第一个节点* @since 1.5*/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 boolean offer(E e) {return add(e);}// Deque operations/*** 在链表开头添加一个节点*/public boolean offerFirst(E e) {addFirst(e);return true;}/*** Inserts the specified element at the end of this list.** @param e the element to insert* @return {@code true} (as specified by {@link Deque#offerLast})* @since 1.6*/public boolean offerLast(E e) {addLast(e);return true;}/*** 返回第一个节点的item*/public E peekFirst() {final Node<E> f = first;return (f == null) ? null : f.item;}/*** 返回最有一个节点的item*/public E peekLast() {final Node<E> l = last;return (l == null) ? null : l.item;}/*** 删除第一个节点,并返会删除的节点*/public E pollFirst() {final Node<E> f = first;return (f == null) ? null : unlinkFirst(f);}/*** 删除最有一个节点,并返回节点*/public E pollLast() {final Node<E> l = last;return (l == null) ? null : unlinkLast(l);}public void push(E e) {addFirst(e);}public E pop() {return removeFirst();}/*** 删除链表中的第一个o*/public boolean removeFirstOccurrence(Object o) {return remove(o);}/*** 删除链表中最后一个*/public boolean removeLastOccurrence(Object o) {if (o == null) {for (Node<E> x = last; x != null; x = x.prev) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = last; x != null; x = x.prev) {if (o.equals(x.item)) {unlink(x);return true;}}}return false;}/*** 返回指定位置之后的一个迭代器*/public ListIterator<E> listIterator(int index) {checkPositionIndex(index);return new ListItr(index);}private class ListItr implements ListIterator<E> {private Node<E> lastReturned;private Node<E> next;private int nextIndex;private int expectedModCount = modCount;ListItr(int index) {// assert isPositionIndex(index);next = (index == size) ? null : node(index);nextIndex = index;}public boolean hasNext() {return nextIndex < size;}public E next() {checkForComodification();if (!hasNext())throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}public boolean hasPrevious() {return nextIndex > 0;}public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned);if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}public void add(E e) {checkForComodification();lastReturned = null;if (next == null)linkLast(e);elselinkBefore(e, next);nextIndex++;expectedModCount++;}public void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);while (modCount == expectedModCount && nextIndex < size) {action.accept(next.item);lastReturned = next;next = next.next;nextIndex++;}checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}/*** @since 1.6*/public Iterator<E> descendingIterator() {return new DescendingIterator();}/*** Adapter to provide descending iterators via ListItr.previous*/private class DescendingIterator implements Iterator<E> {private final ListItr itr = new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}@SuppressWarnings("unchecked")private LinkedList<E> superClone() {try {return (LinkedList<E>) super.clone();} catch (CloneNotSupportedException e) {throw new InternalError(e);}}/*** Returns a shallow copy of this {@code LinkedList}. (The elements* themselves are not cloned.)** @return a shallow copy of this {@code LinkedList} instance*/public Object clone() {LinkedList<E> clone = superClone();// Put clone into "virgin" stateclone.first = clone.last = null;clone.size = 0;clone.modCount = 0;// Initialize clone with our elementsfor (Node<E> x = first; x != null; x = x.next)clone.add(x.item);return clone;}/*** Returns an array containing all of the elements in this list* in proper sequence (from first to last element).** <p>The returned array will be "safe" in that no references to it are* maintained by this list.  (In other words, this method must allocate* a new array).  The caller is thus free to modify the returned array.** <p>This method acts as bridge between array-based and collection-based* APIs.** @return an array containing all of the elements in this list*         in proper sequence*/public Object[] toArray() {Object[] result = new Object[size];int i = 0;for (Node<E> x = first; x != null; x = x.next)result[i++] = x.item;return result;}/*** Returns an array containing all of the elements in this list in* proper sequence (from first to last element); the runtime type of* the returned array is that of the specified array.  If the list fits* in the specified array, it is returned therein.  Otherwise, a new* array is allocated with the runtime type of the specified array and* the size of this list.** <p>If the list fits in the specified array with room to spare (i.e.,* the array has more elements than the list), the element in the array* immediately following the end of the list is set to {@code null}.* (This is useful in determining the length of the list <i>only</i> if* the caller knows that the list does not contain any null elements.)** <p>Like the {@link #toArray()} method, this method acts as bridge between* array-based and collection-based APIs.  Further, this method allows* precise control over the runtime type of the output array, and may,* under certain circumstances, be used to save allocation costs.** <p>Suppose {@code x} is a list known to contain only strings.* The following code can be used to dump the list into a newly* allocated array of {@code String}:** <pre>*     String[] y = x.toArray(new String[0]);</pre>** Note that {@code toArray(new Object[0])} is identical in function to* {@code toArray()}.** @param a the array into which the elements of the list are to*          be stored, if it is big enough; otherwise, a new array of the*          same runtime type is allocated for this purpose.* @return an array containing the elements of the list* @throws ArrayStoreException if the runtime type of the specified array*         is not a supertype of the runtime type of every element in*         this list* @throws NullPointerException if the specified array is null*/@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)a = (T[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);int i = 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;}private static final long serialVersionUID = 876323262645176354L;/*** Saves the state of this {@code LinkedList} instance to a stream* (that is, serializes it).** @serialData The size of the list (the number of elements it*             contains) is emitted (int), followed by all of its*             elements (each an Object) in the proper order.*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {// Write out any hidden serialization magics.defaultWriteObject();// Write out sizes.writeInt(size);// Write out all elements in the proper order.for (Node<E> x = first; x != null; x = x.next)s.writeObject(x.item);}/*** Reconstitutes this {@code LinkedList} instance from a stream* (that is, deserializes it).*/@SuppressWarnings("unchecked")private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {// Read in any hidden serialization magics.defaultReadObject();// Read in sizeint size = s.readInt();// Read in all elements in the proper order.for (int i = 0; i < size; i++)linkLast((E)s.readObject());}/*** Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>* and <em>fail-fast</em> {@link Spliterator} over the elements in this* list.** <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and* {@link Spliterator#ORDERED}.  Overriding implementations should document* the reporting of additional characteristic values.** @implNote* The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}* and implements {@code trySplit} to permit limited parallelism..** @return a {@code Spliterator} over the elements in this list* @since 1.8*/@Overridepublic Spliterator<E> spliterator() {return new LLSpliterator<E>(this, -1, 0);}/** A customized variant of Spliterators.IteratorSpliterator */static final class LLSpliterator<E> implements Spliterator<E> {static final int BATCH_UNIT = 1 << 10;  // batch array size incrementstatic final int MAX_BATCH = 1 << 25;  // max batch array size;final LinkedList<E> list; // null OK unless traversedNode<E> current;      // current node; null until initializedint est;              // size estimate; -1 until first neededint expectedModCount; // initialized when est setint batch;            // batch size for splitsLLSpliterator(LinkedList<E> list, int est, int expectedModCount) {this.list = list;this.est = est;this.expectedModCount = expectedModCount;}final int getEst() {int s; // force initializationfinal LinkedList<E> lst;if ((s = est) < 0) {if ((lst = list) == null)s = est = 0;else {expectedModCount = lst.modCount;current = lst.first;s = est = lst.size;}}return s;}public long estimateSize() { return (long) getEst(); }public Spliterator<E> trySplit() {Node<E> p;int s = getEst();if (s > 1 && (p = current) != null) {int n = batch + BATCH_UNIT;if (n > s)n = s;if (n > MAX_BATCH)n = MAX_BATCH;Object[] a = new Object[n];int j = 0;do { a[j++] = p.item; } while ((p = p.next) != null && j < n);current = p;batch = j;est = s - j;return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);}return null;}public void forEachRemaining(Consumer<? super E> action) {Node<E> p; int n;if (action == null) throw new NullPointerException();if ((n = getEst()) > 0 && (p = current) != null) {current = null;est = 0;do {E e = p.item;p = p.next;action.accept(e);} while (p != null && --n > 0);}if (list.modCount != expectedModCount)throw new ConcurrentModificationException();}public boolean tryAdvance(Consumer<? super E> action) {Node<E> p;if (action == null) throw new NullPointerException();if (getEst() > 0 && (p = current) != null) {--est;E e = p.item;current = p.next;action.accept(e);if (list.modCount != expectedModCount)throw new ConcurrentModificationException();return true;}return false;}public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}}}

posted @ 2019-03-29 18:10 巡山小妖N 阅读(...) 评论(...) 编辑 收藏

LinkedList阅读相关推荐

  1. c mysql datasource_DataSource(mysql/oracle) - 随笔分类 - 我爱si搬砖 - 博客园

    摘要:--单行函数:作用于一行,返回一个值--字符函数select upper(deptno),loc from dept;--结果转大写select lower(loc),loc from dept ...

  2. JDK1.8源码阅读系列之二:LinkedList

    本篇随笔主要描述的是我阅读 LinkedList 源码期间的对于 LinkedList 的一些实现上的个人理解,有不对的地方,请指出- 先来看一下 LinkedList 的继承图: 由于 Abstra ...

  3. LinkedList源码阅读笔记(1.8)

    目录 LinkedList类的注解阅读 LinkedList类的定义 属性的定义 LinkedList构造器 核心方法 校验方法 普通方法 迭代器(iterator&ListIterator) ...

  4. LinkedList源码阅读笔记

    LinkedList源码阅读笔记 初始化 无参的 public LinkedList() {} 初始化的同时添加一个Collection public LinkedList(Collection< ...

  5. java源码阅读LinkedList

    1类签名与注释 public class LinkedList<E>extends AbstractSequentialList<E>implements List<E& ...

  6. Vector和LinkedList源代码阅读笔记

    Vector 1 三个成员变量 elementData: Container elementCount: 有效长度 capacityIncrement: 每次增加的长度 2, 其构造函数没什么特别的, ...

  7. java常用类介绍及源码阅读(LinkedList)

    java.util  类 LinkedList<E> java.lang.Objectjava.util.AbstractCollection<E>java.util.Abst ...

  8. 集合源码阅读:LinkedList

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. # LinkedList -- 增删快.# 1.继承关系:public class LinkedLi ...

  9. ❤️用武侠小说的形式来阅读LinkedList的源码,绝了!

    一.LinkedList 的剖白 大家好,我是 LinkedList,和 ArrayList 是同门师兄弟,但我俩练的内功却完全不同.师兄练的是动态数组,我练的是链表. 问大家一个问题,知道我为什么要 ...

最新文章

  1. 计算机财务应用实验心得,计算机会计实习心得-20210628124643.doc-原创力文档
  2. python折线图样式_011 利用Python进行数据可视化
  3. ado.net连接mysql 类_C# ADO.NET 连接数据库常用到的类及基本操作格式
  4. C#连接池的详细分析(转)
  5. docker修改容器名字
  6. html写界面,C++|Qt后台处理业务(后台登录例子JavaScript给Qt提供数据)
  7. 淮北计算机考试报名,淮北2019年12月计算机等级考试报名入口/注意事项
  8. python selenium定位元素方法_[原创] python selenium 元素定位方法封装
  9. iOS 最新App提交上架流程及部分问题的解决方案2016.12.21,感谢原博主!!!
  10. 拓扑量子计算机 超导 光,科学家发现新型拓扑超导材料 有望推动实现拓扑量子计算...
  11. gcc警告: warning: dereferencing type-punned pointer will break strict-aliasing rules
  12. 视频直播系统源码,比较图片
  13. Flex在线拍照功能
  14. 无需教师端极域电子教室的反控制实现
  15. OSEK网络管理入门
  16. PDF版建筑地面工程施工质量验收规范GB50209-2010附条文说明
  17. android 视频通话框架,Android基于腾讯云实时音视频仿微信视频通话最小化悬浮
  18. apmserv mysql_解决在本地计算无法启动Apmserv-MySQL5.1服务,错误1067:进程意外终止
  19. 大数据产业助力上饶经济转型
  20. 2.5 CMMI2级——配置管理(Configuration Management)

热门文章

  1. 千万千万不要运行的 Linux 命令
  2. php xml expat,PHP 使用 XML Expat 解释xml文件
  3. php页面代码简化,代码求简化
  4. 感恩节祝福html,感恩节祝福英文
  5. as3 java 交互_求大佬用 Java 实现这段 AS3 的 socket 通讯功能
  6. mysql like 中文版_MySQL使用like查询中文不准确的解决方法
  7. fastjson字段改名/设置别名
  8. Linux 利用yum源安装subversion(svn)客户端
  9. 编译 PHP7.0为什么那么慢,CentOS 7编译安装php7.0.7以及可能遇到的问题的解决方案...
  10. 信息通信建设工程预算定额_通信建设工程概预算