1. package java.util;
  2.  
  3. import java.util.function.Consumer;
  4.  
  5. /**
  6. * LinkedList是List和Deque接口的双向链表的实现。实现了所有可选List操作,并允许包括null值。
  7. * LinkedList既然是通过双向链表去实现的,那么它可以被当作堆栈、队列或双端队列进行操作。并且其顺序访问非常高效,而随机访问效率比较低。
  8. * 内部方法,注释会描述为节点的操作(如删除第一个节点),公开的方法会描述为元素的操作(如删除第一个元素)
  9. * 注意,此实现不是同步的。 如果多个线程同时访问一个LinkedList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。
  10. * LinkedList不是线程安全的,如果在多线程中使用(修改),需要在外部作同步处理。
  11. * 这通常是通过同步那些用来封装列表的对象来实现的。
  12. * 但如果没有这样的对象存在,则该列表需要运用{@link Collections#synchronizedList Collections.synchronizedList}来进行“包装”,该方法最好是在创建列表对象时完成,为了避免对列表进行突发的非同步操作。
  13. */
  14.  
  15. public class LinkedList<E>
  16. extends AbstractSequentialList<E>
  17. implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
  18. /**
  19. * 元素数量
  20. */
  21. transient int size = 0;
  22.  
  23. /**
  24. * 首结点引用
  25. */
  26. transient Node<E> first;
  27.  
  28. /**
  29. * 尾节点引用
  30. */
  31. transient Node<E> last;
  32.  
  33. /**
  34. * 无参构造方法
  35. */
  36. public LinkedList() {
  37. }
  38.  
  39. /**
  40. * 通过一个集合初始化LinkedList,元素顺序有这个集合的迭代器返回顺序决定
  41. *
  42. * @param c 其元素将被放入此列表中的集合
  43. * @throws NullPointerException 如果指定的集合是空的
  44. */
  45. public LinkedList(Collection<? extends E> c) {
  46. // 调用无参构造函数
  47. this();
  48. // 添加集合中所有的元素
  49. addAll(c);
  50. }
  51.  
  52. /**
  53. * 头插入,即将节点值为e的节点设置为链表首节点,内部使用
  54. */
  55. private void linkFirst(E e) {
  56. //获取当前首结点引用
  57. final Node<E> f = first;
  58. //构建一个prev值为null,节点值为e,next值为f的新节点newNode
  59. final Node<E> newNode = new Node<>(null, e, f);
  60. //将newNode作为首节点
  61. first = newNode;
  62. //如果原首节点为null,即原链表为null,则链表尾节点也设置为newNode
  63. if (f == null)
  64. last = newNode;
  65. else //否则,原首节点的prev设置为newNode
  66. f.prev = newNode;
  67. size++; //长度+1
  68. modCount++; //修改次数+1
  69. }
  70.  
  71. /**
  72. * 尾插入,即将节点值为e的节点设置为链表的尾节点
  73. */
  74. void linkLast(E e) {
  75. // 获取当前尾结点引用
  76. final Node<E> l = last;
  77. //构建一个prev值为l,节点值为e,next值为null的新节点newNode
  78. final Node<E> newNode = new Node<>(l, e, null);
  79. //将newNode作为尾节点
  80. last = newNode;
  81. //如果原尾节点为null,即原链表为null,则链表首节点也设置为newNode
  82. if (l == null)
  83. first = newNode;
  84. else //否则,原尾节点的next设置为newNode
  85. l.next = newNode;
  86. size++;
  87. modCount++;
  88. }
  89.  
  90. /**
  91. * 中间插入,在非空节点succ之前插入节点值e
  92. */
  93. void linkBefore(E e, Node<E> succ) {
  94. // assert succ != null;
  95. final Node<E> pred = succ.prev;
  96. //构建一个prev值为succ.prev,节点值为e,next值为succ的新节点newNode
  97. final Node<E> newNode = new Node<>(pred, e, succ);
  98. //设置newNode为succ的前节点
  99. succ.prev = newNode;
  100. //如果succ.prev为null,即如果succ为首节点,则将newNode设置为首节点
  101. if (pred == null)
  102. first = newNode;
  103. else //如果succ不是首节点
  104. pred.next = newNode;
  105. size++;
  106. modCount++;
  107. }
  108.  
  109. /**
  110. * 删除首结点,返回存储的元素,内部使用
  111. */
  112. private E unlinkFirst(Node<E> f) {
  113. // 获取首结点存储的元素
  114. final E element = f.item;
  115. // 获取首结点的后继结点
  116. final Node<E> next = f.next;
  117. // 删除首结点
  118. f.item = null;
  119. f.next = null; //便于垃圾回收期清理
  120. // 原来首结点的后继结点设为首结点
  121. first = next;
  122. // 如果原来首结点的后继结点为空,则尾结点设为null
  123. // 否则,原来首结点的后继结点的前驱结点设为null
  124. if (next == null)
  125. last = null;
  126. else
  127. next.prev = null;
  128. size--;
  129. modCount++;
  130. // 返回原来首结点存储的元素
  131. return element;
  132. }
  133.  
  134. /**
  135. * 删除尾结点,返回存储的元素,内部使用
  136. */
  137. private E unlinkLast(Node<E> l) {
  138. // 获取尾结点存储的元素
  139. final E element = l.item;
  140. // 获取尾结点的前驱结点
  141. final Node<E> prev = l.prev;
  142. // 删除尾结点
  143. l.item = null;
  144. l.prev = null; // help GC
  145. // 原来尾结点的前驱结点设为尾结点
  146. last = prev;
  147. // 如果原来尾结点的前驱结点为空,则首结点设为null
  148. // 否则,原来尾结点的前驱结点的后继结点设为null
  149. if (prev == null)
  150. first = null;
  151. else
  152. prev.next = null;
  153. size--;
  154. modCount++;
  155. // 返回原来尾结点存储的元素
  156. return element;
  157. }
  158.  
  159. /**
  160. * 删除指定非空结点,返回存储的元素
  161. */
  162. E unlink(Node<E> x) {
  163. // 获取指定非空结点存储的元素
  164. final E element = x.item;
  165. // 获取指定非空结点的后继结点
  166. final Node<E> next = x.next;
  167. // 获取指定非空结点的前驱结点
  168. final Node<E> prev = x.prev;
  169.  
  170. /**
  171. * 如果指定非空结点的前驱结点为空,则指定非空结点的后继结点设为首结点
  172. * 否则,指定非空结点的后继结点设为指定非空结点的前驱结点的后继结点,
  173. * 指定非空结点的前驱结点设为null
  174. */
  175. if (prev == null) {
  176. first = next;
  177. } else {
  178. prev.next = next;
  179. x.prev = null;
  180. }
  181.  
  182. /**
  183. * 如果指定非空结点的后继结点为空,则指定非空结点的前驱结点设为尾结点
  184. * 否则,指定非空结点的前驱结点设为指定非空结点的后继结点的前驱结点,
  185. * 指定非空结点的后继结点设为null
  186. */
  187. if (next == null) {
  188. last = prev;
  189. } else {
  190. next.prev = prev;
  191. x.next = null;
  192. }
  193.  
  194. // 指定非空结点存储的元素设为null
  195. x.item = null;
  196. size--;
  197. modCount++;
  198. // 返回指定非空结点存储的元素
  199. return element;
  200. }
  201.  
  202. /**
  203. * 获取首结点存储的元素
  204. *
  205. * @return 首结点存储的元素
  206. * @throws NoSuchElementException 如果链表为空
  207. */
  208. public E getFirst() {
  209. // 获取首结点引用
  210. final Node<E> f = first;
  211. // 如果首结点为空,则抛出无该元素异常
  212. if (f == null)
  213. throw new NoSuchElementException();
  214. // 返回首结点存储的元素
  215. return f.item;
  216. }
  217.  
  218. /**
  219. * 获取尾结点存储的元素
  220. *
  221. * @return 尾结点存储的元素
  222. * @throws NoSuchElementException 如果链表为空
  223. */
  224. public E getLast() {
  225. // 获取尾结点引用
  226. final Node<E> l = last;
  227. // 如果尾结点为空,则抛出无该元素异常
  228. if (l == null)
  229. throw new NoSuchElementException();
  230. // 返回尾结点存储的元素
  231. return l.item;
  232. }
  233.  
  234. /**
  235. * 删除首结点,返回存储的元素
  236. *
  237. * @return 首结点存储的元素
  238. * @throws NoSuchElementException 如果链表为空
  239. */
  240. public E removeFirst() {
  241. // 获取首结点引用
  242. final Node<E> f = first;
  243. // 如果首结点为空,则抛出无该元素异常
  244. if (f == null)
  245. throw new NoSuchElementException();
  246. // 删除首结点,返回存储的元素
  247. return unlinkFirst(f);
  248. }
  249.  
  250. /**
  251. * 删除尾结点,返回存储的元素
  252. *
  253. * @return 尾结点存储的元素
  254. * @throws NoSuchElementException 如果链表为空
  255. */
  256. public E removeLast() {
  257. // 获取尾结点引用
  258. final Node<E> l = last;
  259. // 如果尾结点为空,则抛出无该元素异常
  260. if (l == null)
  261. throw new NoSuchElementException();
  262. // 删除尾结点,返回存储的元素
  263. return unlinkLast(l);
  264. }
  265.  
  266. /**
  267. * 头部插入指定元素
  268. *
  269. * @param e 要添加的元素
  270. */
  271. public void addFirst(E e) {
  272. // 通过头插法来插入指定元素
  273. linkFirst(e);
  274. }
  275.  
  276. /**
  277. * 尾部插入指定元素,该方法等价于add()
  278. *
  279. * @param e the element to add
  280. */
  281. public void addLast(E e) {
  282. linkLast(e);
  283. }
  284.  
  285. /**
  286. * 判断是否包含指定元素
  287. *
  288. * @param o 判断链表是否包含的元素
  289. * @return {@code true} 如果链表包含指定的元素
  290. */
  291. public boolean contains(Object o) {
  292. //返回指定元素的索引位置,不存在就返回-1,然后比较返回bool值
  293. return indexOf(o) != -1;
  294. }
  295.  
  296. /**
  297. * 获取元素数量
  298. *
  299. * @return 元素数量
  300. */
  301. public int size() {
  302. return size;
  303. }
  304.  
  305. /**
  306. * 插入指定元素,返回操作结果,默认添加到末尾作为最后一个元素
  307. *
  308. * @param e 要添加到此链表中的元素
  309. * @return {@code true} (as specified by {@link Collection#add})
  310. */
  311. public boolean add(E e) {
  312. // 通过尾插法来插入指定元素
  313. linkLast(e);
  314. return true;
  315. }
  316.  
  317. /**
  318. * 删除指定元素,默认从first节点开始,删除第一次出现的那个元素
  319. *
  320. * @param o 要从该列表中删除的元素(如果存在)
  321. * @return {@code true} 如果这个列表包含指定的元素
  322. */
  323. public boolean remove(Object o) {
  324. //会根据是否为null分开处理。若值不是null,会用到对象的equals()方法
  325. if (o == null) {
  326. // 遍历链表,查找到指定元素后删除该结点,返回true
  327. for (Node<E> x = first; x != null; x = x.next) {
  328. if (x.item == null) {
  329. unlink(x);
  330. return true;
  331. }
  332. }
  333. } else {
  334. for (Node<E> x = first; x != null; x = x.next) {
  335. if (o.equals(x.item)) {
  336. unlink(x);
  337. return true;
  338. }
  339. }
  340. }
  341. // 查找失败
  342. return false;
  343. }
  344.  
  345. /**
  346. * 将集合插入到链表尾部,即开始索引位置为size
  347. *
  348. * @param c 包含要添加到此链表中的元素的集合
  349. * @return {@code true} 如果该链表因添加而改变
  350. * @throws NullPointerException 如果指定的集合是空的
  351. */
  352. public boolean addAll(Collection<? extends E> c) {
  353. return addAll(size, c);
  354. }
  355.  
  356. /**
  357. * 将集合从指定位置开始插入
  358. *
  359. * @param index 在哪个索引处前插入指定集合中的第一个元素
  360. * @param c 包含要添加到此链表中的元素的集合
  361. * @return {@code true} 如果该链表因添加而改变
  362. * @throws IndexOutOfBoundsException {@inheritDoc}
  363. * @throws NullPointerException 如果指定的集合是空的
  364. */
  365. public boolean addAll(int index, Collection<? extends E> c) {
  366. //检查索引是否正确(0<=index<=size)
  367. checkPositionIndex(index);
  368. //得到元素数组
  369. Object[] a = c.toArray();
  370. //得到元素个数
  371. int numNew = a.length;
  372. //若没有元素要添加,直接返回false
  373. if (numNew == 0)
  374. return false;
  375. //succ指向当前需要插入节点的位置,pred指向其前一个节点
  376. Node<E> pred, succ;
  377. //如果是在末尾开始添加,当前节点后一个节点初始化为null,前一个节点为尾节点
  378. if (index == size) {
  379. succ = null;
  380. pred = last;
  381. } else { //如果不是从末尾开始添加,当前位置的节点为指定位置的节点,前一个节点为要添加的节点的前一个节点
  382. succ = node(index);
  383. pred = succ.prev;
  384. }
  385. //遍历数组并添加到列表中
  386. for (Object o : a) {
  387. @SuppressWarnings("unchecked") E e = (E) o;
  388. //将元素值e,前继节点pred“封装”为一个新节点newNode
  389. Node<E> newNode = new Node<>(pred, e, null);
  390. //如果原链表为null,则新插入的节点作为链表首节点
  391. if (pred == null)
  392. first = newNode;
  393. else
  394. pred.next = newNode; //如果存在前节点,前节点会向后指向新加的节点
  395. pred = newNode; //pred指针向后移动,指向下一个需插入节点位置的前一个节点
  396. }
  397. //如果是从最后开始添加的,则最后添加的节点成为尾节点
  398. if (succ == null) {
  399. last = pred;
  400. } else {
  401. pred.next = succ; //如果不是从最后开始添加的,则最后添加的节点向后指向之前得到的后续第一个节点
  402. succ.prev = pred; //当前,后续的第一个节点也应改为向前指向最后一个添加的节点
  403. }
  404.  
  405. size += numNew;
  406. modCount++;
  407. return true;
  408. }
  409.  
  410. /**
  411. * 删除所有元素
  412. */
  413. public void clear() {
  414. //遍历链表,删除所有结点,方便gc回收垃圾
  415. for (Node<E> x = first; x != null; ) {
  416. Node<E> next = x.next;
  417. x.item = null;
  418. x.next = null;
  419. x.prev = null;
  420. x = next;
  421. }
  422. // 首尾结点置空
  423. first = last = null;
  424. // 元素数量置0
  425. size = 0;
  426. modCount++;
  427. }
  428.  
  429. // 位置访问操作
  430.  
  431. /**
  432. * 获取指定位置的元素
  433. *
  434. * @param index 要返回的元素的索引
  435. * @return 该链表中指定位置的元素
  436. * @throws IndexOutOfBoundsException {@inheritDoc}
  437. */
  438. public E get(int index) {
  439. // 判断指定位置是否合法
  440. checkElementIndex(index);
  441. // 返回指定位置的元素
  442. return node(index).item;
  443. }
  444.  
  445. /**
  446. * 修改指定位置的元素,返回之前元素
  447. *
  448. * @param index 要替换的元素的索引
  449. * @param element 要存储在指定位置的元素
  450. * @return 之前在指定位置的元素
  451. * @throws IndexOutOfBoundsException {@inheritDoc}
  452. */
  453. public E set(int index, E element) {
  454. // 判断指定位置是否合法
  455. checkElementIndex(index);
  456. // 获取指定位置的结点
  457. Node<E> x = node(index);
  458. // 获取该结点存储的元素
  459. E oldVal = x.item;
  460. // 修改该结点存储的元素
  461. x.item = element;
  462. // 返回该结点存储的之前的元素
  463. return oldVal;
  464. }
  465.  
  466. /**
  467. * 在指定位置前插入指定元素
  468. *
  469. * @param index 指定元素将被插入的索引
  470. * @param element 要插入的元素
  471. * @throws IndexOutOfBoundsException {@inheritDoc}
  472. */
  473. public void add(int index, E element) {
  474. // 判断指定位置是否合法
  475. checkPositionIndex(index);
  476. // 如果指定位置在尾部,则通过尾插法来插入指定元素
  477. if (index == size)
  478. linkLast(element);
  479. else //如果指定位置不是尾部,则添加到指定位置前
  480. linkBefore(element, node(index));
  481. }
  482.  
  483. /**
  484. * 删除指定位置的元素,返回之前元素
  485. *
  486. * @param index 要删除的元素的索引
  487. * @return 之前在指定位置的元素
  488. * @throws IndexOutOfBoundsException {@inheritDoc}
  489. */
  490. public E remove(int index) {
  491. // 判断指定位置是否合法
  492. checkElementIndex(index);
  493. // 删除指定位置的结点,返回之前元素
  494. return unlink(node(index));
  495. }
  496.  
  497. /**
  498. * 判断指定位置是否合法
  499. */
  500. private boolean isElementIndex(int index) {
  501. return index >= 0 && index < size;
  502. }
  503.  
  504. /**
  505. * 判断迭代器遍历时或插入元素时指定位置是否合法
  506. */
  507. private boolean isPositionIndex(int index) {
  508. return index >= 0 && index <= size;
  509. }
  510.  
  511. /**
  512. * 获取越界异常信息
  513. */
  514. private String outOfBoundsMsg(int index) {
  515. return "Index: " + index + ", Size: " + size;
  516. }
  517.  
  518. /**
  519. * 判断指定位置是否合法
  520. *
  521. * @param index
  522. */
  523. private void checkElementIndex(int index) {
  524. if (!isElementIndex(index))
  525. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  526. }
  527.  
  528. /**
  529. * 判断指定位置是否合法
  530. *
  531. * @param index
  532. */
  533. private void checkPositionIndex(int index) {
  534. if (!isPositionIndex(index))
  535. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  536. }
  537.  
  538. /**
  539. * 获取指定下标的结点,index从0开始
  540. */
  541. Node<E> node(int index) {
  542. // 如果指定下标<一半元素数量,则从首结点开始遍历
  543. // 否则,从尾结点开始遍历
  544. if (index < (size >> 1)) {
  545. Node<E> x = first;
  546. for (int i = 0; i < index; i++)
  547. x = x.next;
  548. return x;
  549. } else {
  550. Node<E> x = last;
  551. for (int i = size - 1; i > index; i--)
  552. x = x.prev;
  553. return x;
  554. }
  555. }
  556.  
  557. // 查询操作
  558.  
  559. /**
  560. * 获取顺序下首次出现指定元素的位置
  561. * 如果返回结果是-1,则表示不存在该元素
  562. *
  563. * @param o 要查找的元素
  564. * @return the index of the first occurrence of the specified element in
  565. * this list, or -1 if this list does not contain the element
  566. */
  567. public int indexOf(Object o) {
  568. int index = 0;
  569. if (o == null) {
  570. // 遍历链表,顺序查找指定元素
  571. for (Node<E> x = first; x != null; x = x.next) {
  572. if (x.item == null)
  573. return index;
  574. index++;
  575. }
  576. } else {
  577. for (Node<E> x = first; x != null; x = x.next) {
  578. if (o.equals(x.item))
  579. return index;
  580. index++;
  581. }
  582. }
  583. return -1;
  584. }
  585.  
  586. /**
  587. * 获取逆序下首次出现指定元素的位置
  588. * 如果返回结果是-1,则表示不存在该元素
  589. *
  590. * @param o 要查找的元素
  591. * @return the index of the last occurrence of the specified element in
  592. * this list, or -1 if this list does not contain the element
  593. */
  594. public int lastIndexOf(Object o) {
  595. int index = size;
  596. if (o == null) {
  597. // 遍历链表,逆序查找指定元素
  598. for (Node<E> x = last; x != null; x = x.prev) {
  599. index--;
  600. if (x.item == null)
  601. return index;
  602. }
  603. } else {
  604. for (Node<E> x = last; x != null; x = x.prev) {
  605. index--;
  606. if (o.equals(x.item))
  607. return index;
  608. }
  609. }
  610. return -1;
  611. }
  612.  
  613. // 队列操作
  614.  
  615. /**
  616. * 出队(从前端),获得第一个元素,不存在会返回null,不会删除元素(节点)
  617. * 获取首元素
  618. *
  619. * @return the head of this list, or {@code null} 如果链表为空
  620. * @since 1.5
  621. */
  622. public E peek() {
  623. final Node<E> f = first;
  624. // 如果首结点为空,则返回null
  625. // 否则,返回首结点存储的元素
  626. return (f == null) ? null : f.item;
  627. }
  628.  
  629. /**
  630. * 出队(从前端),不删除元素,若为null会抛出异常而不是返回null
  631. * 获取首元素
  632. *
  633. * @return the head of this list
  634. * @throws NoSuchElementException 如果链表为空
  635. * @since 1.5
  636. */
  637. public E element() {
  638. // 返回首结点存储的元素
  639. return getFirst();
  640. }
  641.  
  642. /**
  643. * 出队(从前端),如果不存在会返回null,存在的话会返回值并移除这个元素(节点)
  644. * 获取并删除首元素
  645. *
  646. * @return the head of this list, or {@code null} 如果链表为空
  647. * @since 1.5
  648. */
  649. public E poll() {
  650. // 获取首结点引用
  651. final Node<E> f = first;
  652. // 如果首结点为空,则返回null
  653. // 否则,删除首结点,返回首结点存储的元素
  654. return (f == null) ? null : unlinkFirst(f);
  655. }
  656.  
  657. /**
  658. * 出队(从前端),如果不存在会抛出异常而不是返回null,存在的话会返回值并移除这个元素(节点)
  659. * 获取并删除首元素
  660. *
  661. * @return the head of this list
  662. * @throws NoSuchElementException 如果链表为空
  663. * @since 1.5
  664. */
  665. public E remove() {
  666. // 删除首结点,返回首结点存储的元素
  667. return removeFirst();
  668. }
  669.  
  670. /**
  671. * 入队(从后端),始终返回true
  672. *
  673. * @param e the element to add
  674. * @return {@code true} (as specified by {@link Queue#offer})
  675. * @since 1.5
  676. */
  677. public boolean offer(E e) {
  678. // 通过尾插法插入指定元素,返回操作结果
  679. return add(e);
  680. }
  681.  
  682. // 双端队列操作
  683.  
  684. /**
  685. * 入队(从前端),始终返回true
  686. *
  687. * @param e 要插入的元素
  688. * @return {@code true} (as specified by {@link Deque#offerFirst})
  689. * @since 1.6
  690. */
  691. public boolean offerFirst(E e) {
  692. // 通过尾插法来插入指定元素
  693. addFirst(e);
  694. return true;
  695. }
  696.  
  697. /**
  698. * 入队(从后端),始终返回true
  699. *
  700. * @param e 要插入的元素
  701. * @return {@code true} (as specified by {@link Deque#offerLast})
  702. * @since 1.6
  703. */
  704. public boolean offerLast(E e) {
  705. // 通过尾插法来插入指定元素
  706. addLast(e);
  707. return true;
  708. }
  709.  
  710. /**
  711. * 出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点)
  712. *
  713. * @return the first element of this list, or {@code null}
  714. * 如果链表为空
  715. * @since 1.6
  716. */
  717. public E peekFirst() {
  718. // 获取首结点引用
  719. final Node<E> f = first;
  720. // 如果首结点为空,则返回null
  721. // 否则,返回首结点存储的元素
  722. return (f == null) ? null : f.item;
  723. }
  724.  
  725. /**
  726. * 出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点)
  727. *
  728. * @return the last element of this list, or {@code null}
  729. * 如果链表为空
  730. * @since 1.6
  731. */
  732. public E peekLast() {
  733. // 获取尾结点引用
  734. final Node<E> l = last;
  735. // 如果尾结点为空,则返回null
  736. // 否则,返回尾结点存储的元素
  737. return (l == null) ? null : l.item;
  738. }
  739.  
  740. /**
  741. * 出队(从前端),获得第一个元素,不存在会返回null,会删除元素(节点)
  742. *
  743. * @return the first element of this list, or {@code null} if
  744. * this list is empty
  745. * @since 1.6
  746. */
  747. public E pollFirst() {
  748. // 获取首结点引用
  749. final Node<E> f = first;
  750. // 如果首结点为空,则返回null
  751. // 否则,删除首结点,返回首结点存储的元素
  752. return (f == null) ? null : unlinkFirst(f);
  753. }
  754.  
  755. /**
  756. * 出队(从后端),获得最后一个元素,不存在会返回null,会删除元素(节点)
  757. *
  758. * @return the last element of this list, or {@code null} if
  759. * this list is empty
  760. * @since 1.6
  761. */
  762. public E pollLast() {
  763. // 获取尾结点引用
  764. final Node<E> l = last;
  765. // 如果尾结点为空,则返回null
  766. // 否则,删除尾结点,返回尾结点存储的元素
  767. return (l == null) ? null : unlinkLast(l);
  768. }
  769.  
  770. /**
  771. * 入栈,从前面添加
  772. *
  773. * @param e the element to push
  774. * @since 1.6
  775. */
  776. public void push(E e) {
  777. // 通过头插法来插入指定元素
  778. addFirst(e);
  779. }
  780.  
  781. /**
  782. * 出栈,返回栈顶元素,从前面移除(会删除)
  783. *
  784. * @return the element at the front of this list (which is the top
  785. * of the stack represented by this list)
  786. * @throws NoSuchElementException 如果链表为空
  787. * @since 1.6
  788. */
  789. public E pop() {
  790. // 删除首结点,返回首结点存储的元素
  791. return removeFirst();
  792. }
  793.  
  794. /**
  795. * 删除顺序下首次出现的指定元素,返回操作结果
  796. *
  797. * @param o 要从该列表中删除的元素(如果存在)
  798. * @return {@code true} 如果链表包含指定的元素
  799. * @since 1.6
  800. */
  801. public boolean removeFirstOccurrence(Object o) {
  802. // 删除顺序下首次出现的指定元素对应的结点,返回操作结果
  803. return remove(o);
  804. }
  805.  
  806. /**
  807. * 删除逆序下首次出现的指定元素,返回操作结果
  808. *
  809. * @param o 要从该列表中删除的元素(如果存在)
  810. * @return {@code true} 如果链表包含指定的元素
  811. * @since 1.6
  812. */
  813. public boolean removeLastOccurrence(Object o) {
  814. //由于LinkedList中允许存放null,因此下面通过两种情况来分别处理
  815. if (o == null) {
  816. // 遍历链表,从尾结点开始查找指定元素
  817. // 如果查找成功,删除该结点,返回true
  818. for (Node<E> x = last; x != null; x = x.prev) {
  819. if (x.item == null) {
  820. unlink(x);
  821. return true;
  822. }
  823. }
  824. } else {
  825. for (Node<E> x = last; x != null; x = x.prev) {
  826. if (o.equals(x.item)) {
  827. unlink(x);
  828. return true;
  829. }
  830. }
  831. }
  832. // 查找失败
  833. return false;
  834. }
  835.  
  836. /**
  837. * Returns a list-iterator of the elements in this list (in proper
  838. * sequence), starting at the specified position in the list.
  839. * Obeys the general contract of {@code List.listIterator(int)}.<p>
  840. * <p>
  841. * The list-iterator is <i>fail-fast</i>: if the list is structurally
  842. * modified at any time after the Iterator is created, in any way except
  843. * through the list-iterator's own {@code remove} or {@code add}
  844. * methods, the list-iterator will throw a
  845. * {@code ConcurrentModificationException}. Thus, in the face of
  846. * concurrent modification, the iterator fails quickly and cleanly, rather
  847. * than risking arbitrary, non-deterministic behavior at an undetermined
  848. * time in the future.
  849. *
  850. * @param index index of the first element to be returned from the
  851. * list-iterator (by a call to {@code next})
  852. * @return a ListIterator of the elements in this list (in proper
  853. * sequence), starting at the specified position in the list
  854. * @throws IndexOutOfBoundsException {@inheritDoc}
  855. * @see List#listIterator(int)
  856. */
  857. public ListIterator<E> listIterator(int index) {
  858. checkPositionIndex(index);
  859. return new ListItr(index);
  860. }
  861.  
  862. private class ListItr implements ListIterator<E> {
  863. private Node<E> lastReturned;
  864. private Node<E> next;
  865. private int nextIndex;
  866. private int expectedModCount = modCount;
  867.  
  868. ListItr(int index) {
  869. // assert isPositionIndex(index);
  870. next = (index == size) ? null : node(index);
  871. nextIndex = index;
  872. }
  873.  
  874. public boolean hasNext() {
  875. return nextIndex < size;
  876. }
  877.  
  878. public E next() {
  879. checkForComodification();
  880. if (!hasNext())
  881. throw new NoSuchElementException();
  882.  
  883. lastReturned = next;
  884. next = next.next;
  885. nextIndex++;
  886. return lastReturned.item;
  887. }
  888.  
  889. public boolean hasPrevious() {
  890. return nextIndex > 0;
  891. }
  892.  
  893. public E previous() {
  894. checkForComodification();
  895. if (!hasPrevious())
  896. throw new NoSuchElementException();
  897.  
  898. lastReturned = next = (next == null) ? last : next.prev;
  899. nextIndex--;
  900. return lastReturned.item;
  901. }
  902.  
  903. public int nextIndex() {
  904. return nextIndex;
  905. }
  906.  
  907. public int previousIndex() {
  908. return nextIndex - 1;
  909. }
  910.  
  911. public void remove() {
  912. checkForComodification();
  913. if (lastReturned == null)
  914. throw new IllegalStateException();
  915.  
  916. Node<E> lastNext = lastReturned.next;
  917. unlink(lastReturned);
  918. if (next == lastReturned)
  919. next = lastNext;
  920. else
  921. nextIndex--;
  922. lastReturned = null;
  923. expectedModCount++;
  924. }
  925.  
  926. public void set(E e) {
  927. if (lastReturned == null)
  928. throw new IllegalStateException();
  929. checkForComodification();
  930. lastReturned.item = e;
  931. }
  932.  
  933. public void add(E e) {
  934. checkForComodification();
  935. lastReturned = null;
  936. if (next == null)
  937. linkLast(e);
  938. else
  939. linkBefore(e, next);
  940. nextIndex++;
  941. expectedModCount++;
  942. }
  943.  
  944. public void forEachRemaining(Consumer<? super E> action) {
  945. Objects.requireNonNull(action);
  946. while (modCount == expectedModCount && nextIndex < size) {
  947. action.accept(next.item);
  948. lastReturned = next;
  949. next = next.next;
  950. nextIndex++;
  951. }
  952. checkForComodification();
  953. }
  954.  
  955. final void checkForComodification() {
  956. if (modCount != expectedModCount)
  957. throw new ConcurrentModificationException();
  958. }
  959. }
  960.  
  961. /**
  962. * 节点的数据结构,包含前后节点的引用和当前节点
  963. *
  964. * @param <E>
  965. */
  966. private static class Node<E> {
  967. // 存储的元素
  968. E item;
  969. // 后继结点
  970. Node<E> next;
  971. // 前驱结点
  972. Node<E> prev;
  973.  
  974. // 前驱结点、存储的元素和后继结点作为参数的构造方法
  975. Node(Node<E> prev, E element, Node<E> next) {
  976. this.item = element;
  977. this.next = next;
  978. this.prev = prev;
  979. }
  980. }
  981.  
  982. /**
  983. * 返回迭代器
  984. *
  985. * @since 1.6
  986. */
  987. public Iterator<E> descendingIterator() {
  988. return new DescendingIterator();
  989. }
  990.  
  991. /**
  992. * 因为采用链表实现,所以迭代器很简单
  993. */
  994. private class DescendingIterator implements Iterator<E> {
  995. private final ListItr itr = new ListItr(size());
  996.  
  997. public boolean hasNext() {
  998. return itr.hasPrevious();
  999. }
  1000.  
  1001. public E next() {
  1002. return itr.previous();
  1003. }
  1004.  
  1005. public void remove() {
  1006. itr.remove();
  1007. }
  1008. }
  1009.  
  1010. /**
  1011. * 父类克隆方法
  1012. */
  1013. @SuppressWarnings("unchecked")
  1014. private LinkedList<E> superClone() {
  1015. try {
  1016. return (LinkedList<E>) super.clone();
  1017. } catch (CloneNotSupportedException e) {
  1018. throw new InternalError(e);
  1019. }
  1020. }
  1021.  
  1022. /**
  1023. * 克隆,浅拷贝
  1024. *
  1025. * @return a shallow copy of this {@code LinkedList} instance
  1026. */
  1027. public Object clone() {
  1028. LinkedList<E> clone = superClone();
  1029.  
  1030. // 链表初始化
  1031. clone.first = clone.last = null;
  1032. clone.size = 0;
  1033. clone.modCount = 0;
  1034.  
  1035. // 插入结点
  1036. for (Node<E> x = first; x != null; x = x.next)
  1037. clone.add(x.item);
  1038. // 返回克隆后的对象引用
  1039. return clone;
  1040. }
  1041.  
  1042. /**
  1043. * Returns an array containing all of the elements in this list
  1044. * in proper sequence (from first to last element).
  1045. * <p>
  1046. * <p>The returned array will be "safe" in that no references to it are
  1047. * maintained by this list. (In other words, this method must allocate
  1048. * a new array). The caller is thus free to modify the returned array.
  1049. * <p>
  1050. * <p>This method acts as bridge between array-based and collection-based
  1051. * APIs.
  1052. *
  1053. * @return an array containing all of the elements in this list
  1054. * in proper sequence
  1055. */
  1056. public Object[] toArray() {
  1057. Object[] result = new Object[size];
  1058. int i = 0;
  1059. for (Node<E> x = first; x != null; x = x.next)
  1060. result[i++] = x.item;
  1061. return result;
  1062. }
  1063.  
  1064. /**
  1065. * Returns an array containing all of the elements in this list in
  1066. * proper sequence (from first to last element); the runtime type of
  1067. * the returned array is that of the specified array. If the list fits
  1068. * in the specified array, it is returned therein. Otherwise, a new
  1069. * array is allocated with the runtime type of the specified array and
  1070. * the size of this list.
  1071. * <p>
  1072. * <p>If the list fits in the specified array with room to spare (i.e.,
  1073. * the array has more elements than the list), the element in the array
  1074. * immediately following the end of the list is set to {@code null}.
  1075. * (This is useful in determining the length of the list <i>only</i> if
  1076. * the caller knows that the list does not contain any null elements.)
  1077. * <p>
  1078. * <p>Like the {@link #toArray()} method, this method acts as bridge between
  1079. * array-based and collection-based APIs. Further, this method allows
  1080. * precise control over the runtime type of the output array, and may,
  1081. * under certain circumstances, be used to save allocation costs.
  1082. * <p>
  1083. * <p>Suppose {@code x} is a list known to contain only strings.
  1084. * The following code can be used to dump the list into a newly
  1085. * allocated array of {@code String}:
  1086. * <p>
  1087. * <pre>
  1088. * String[] y = x.toArray(new String[0]);</pre>
  1089. * <p>
  1090. * Note that {@code toArray(new Object[0])} is identical in function to
  1091. * {@code toArray()}.
  1092. *
  1093. * @param a the array into which the elements of the list are to
  1094. * be stored, if it is big enough; otherwise, a new array of the
  1095. * same runtime type is allocated for this purpose.
  1096. * @return an array containing the elements of the list
  1097. * @throws ArrayStoreException if the runtime type of the specified array
  1098. * is not a supertype of the runtime type of every element in
  1099. * this list
  1100. * @throws NullPointerException if the specified array is null
  1101. */
  1102. @SuppressWarnings("unchecked")
  1103. public <T> T[] toArray(T[] a) {
  1104. if (a.length < size)
  1105. a = (T[]) java.lang.reflect.Array.newInstance(
  1106. a.getClass().getComponentType(), size);
  1107. int i = 0;
  1108. Object[] result = a;
  1109. for (Node<E> x = first; x != null; x = x.next)
  1110. result[i++] = x.item;
  1111.  
  1112. if (a.length > size)
  1113. a[size] = null;
  1114.  
  1115. return a;
  1116. }
  1117.  
  1118. private static final long serialVersionUID = 876323262645176354L;
  1119.  
  1120. /**
  1121. * 序列化
  1122. */
  1123. private void writeObject(java.io.ObjectOutputStream s)
  1124. throws java.io.IOException {
  1125. // 默认序列化
  1126. s.defaultWriteObject();
  1127.  
  1128. // 写入元素数量
  1129. s.writeInt(size);
  1130.  
  1131. // 遍历链表,写入所有元素
  1132. for (Node<E> x = first; x != null; x = x.next)
  1133. s.writeObject(x.item);
  1134. }
  1135.  
  1136. /**
  1137. * 反序列化
  1138. */
  1139. @SuppressWarnings("unchecked")
  1140. private void readObject(java.io.ObjectInputStream s)
  1141. throws java.io.IOException, ClassNotFoundException {
  1142. // 默认反序列化
  1143. s.defaultReadObject();
  1144.  
  1145. // 读取元素数量
  1146. int size = s.readInt();
  1147.  
  1148. // 遍历链表,读取所有元素并尾部插入
  1149. for (int i = 0; i < size; i++)
  1150. linkLast((E) s.readObject());
  1151. }
  1152.  
  1153. /**
  1154. * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
  1155. * and <em>fail-fast</em> {@link Spliterator} over the elements in this
  1156. * list.
  1157. * <p>
  1158. * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
  1159. * {@link Spliterator#ORDERED}. Overriding implementations should document
  1160. * the reporting of additional characteristic values.
  1161. *
  1162. * @return a {@code Spliterator} over the elements in this list
  1163. * @implNote The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}
  1164. * and implements {@code trySplit} to permit limited parallelism..
  1165. * @since 1.8
  1166. */
  1167. @Override
  1168. public Spliterator<E> spliterator() {
  1169. return new LLSpliterator<E>(this, -1, 0);
  1170. }
  1171.  
  1172. /**
  1173. * A customized variant of Spliterators.IteratorSpliterator
  1174. */
  1175. static final class LLSpliterator<E> implements Spliterator<E> {
  1176. static final int BATCH_UNIT = 1 << 10; // batch array size increment
  1177. static final int MAX_BATCH = 1 << 25; // max batch array size;
  1178. final LinkedList<E> list; // null OK unless traversed
  1179. Node<E> current; // current node; null until initialized
  1180. int est; // size estimate; -1 until first needed
  1181. int expectedModCount; // initialized when est set
  1182. int batch; // batch size for splits
  1183.  
  1184. LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
  1185. this.list = list;
  1186. this.est = est;
  1187. this.expectedModCount = expectedModCount;
  1188. }
  1189.  
  1190. final int getEst() {
  1191. int s; // force initialization
  1192. final LinkedList<E> lst;
  1193. if ((s = est) < 0) {
  1194. if ((lst = list) == null)
  1195. s = est = 0;
  1196. else {
  1197. expectedModCount = lst.modCount;
  1198. current = lst.first;
  1199. s = est = lst.size;
  1200. }
  1201. }
  1202. return s;
  1203. }
  1204.  
  1205. public long estimateSize() {
  1206. return (long) getEst();
  1207. }
  1208.  
  1209. public Spliterator<E> trySplit() {
  1210. Node<E> p;
  1211. int s = getEst();
  1212. if (s > 1 && (p = current) != null) {
  1213. int n = batch + BATCH_UNIT;
  1214. if (n > s)
  1215. n = s;
  1216. if (n > MAX_BATCH)
  1217. n = MAX_BATCH;
  1218. Object[] a = new Object[n];
  1219. int j = 0;
  1220. do {
  1221. a[j++] = p.item;
  1222. } while ((p = p.next) != null && j < n);
  1223. current = p;
  1224. batch = j;
  1225. est = s - j;
  1226. return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
  1227. }
  1228. return null;
  1229. }
  1230.  
  1231. public void forEachRemaining(Consumer<? super E> action) {
  1232. Node<E> p;
  1233. int n;
  1234. if (action == null) throw new NullPointerException();
  1235. if ((n = getEst()) > 0 && (p = current) != null) {
  1236. current = null;
  1237. est = 0;
  1238. do {
  1239. E e = p.item;
  1240. p = p.next;
  1241. action.accept(e);
  1242. } while (p != null && --n > 0);
  1243. }
  1244. if (list.modCount != expectedModCount)
  1245. throw new ConcurrentModificationException();
  1246. }
  1247.  
  1248. public boolean tryAdvance(Consumer<? super E> action) {
  1249. Node<E> p;
  1250. if (action == null) throw new NullPointerException();
  1251. if (getEst() > 0 && (p = current) != null) {
  1252. --est;
  1253. E e = p.item;
  1254. current = p.next;
  1255. action.accept(e);
  1256. if (list.modCount != expectedModCount)
  1257. throw new ConcurrentModificationException();
  1258. return true;
  1259. }
  1260. return false;
  1261. }
  1262.  
  1263. public int characteristics() {
  1264. return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
  1265. }
  1266. }
  1267.  
  1268. }

LinkedList源码解析(JDK1.8)的更多相关文章

  1. LinkedList源码解析

    LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明.1.链表的概念链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和 ...

  2. Java集合:LinkedList源码解析

    Java集合---LinkedList源码解析   一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...

  3. 给jdk写注释系列之jdk1.6容器(2)-LinkedList源码解析

    LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明.   1.链表的概念      链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链 ...

  4. Java集合---LinkedList源码解析

    一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...

  5. ava集合---LinkedList源码解析

    一.源码解析 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E ...

  6. 源码解析JDK1.8-HashMap链表成环的问题解决方案

    前言 上篇文章详解介绍了HashMap在JDK1.7版本中链表成环的原因,今天介绍下JDK1.8针对HashMap线程安全问题的解决方案. jdk1.8 扩容源码解析 public class Has ...

  7. Java集合-ArrayList源码解析-JDK1.8

    ◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...

  8. Java集合框架之二:LinkedList源码解析

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! LinkedList底层是通过双向循环链表来实现的,其结构如下图所示: 链表的组成元素我们称之为节点,节点由三部分组成:前一个节点的引用地 ...

  9. Java集合之LinkedList源码解析

    LinkedList简介 LinkedList基于双向链表,即FIFO(先进先出)和FILO(先进后出)都是支持的,这样它可以作为堆栈,队列使用 继承AbstractSequentialList,该类 ...

  10. ArrayList、CopyOnWriteArrayList源码解析(JDK1.8)

    本篇文章主要是学习后的知识记录,存在不足,或许不够深入,还请谅解. 目录 ArrayList源码解析 ArrayList中的变量 ArrayList构造函数 ArrayList中的add方法 Arra ...

随机推荐

  1. 记录 serverSocket socket 输入,输出流,关闭顺序,阻塞,PrintWriter的一些问题.

    关于socket.getOutputStream() 的一些问题, OutputStream的flush是一个空方法,所以需要另一个实现了Flush的流来包装一下 这里为什么使用PrintWriter ...

  2. html标签详解

    html标签详解   <!DOCTYPE> 标签 <!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前. <!DOCTYPE ...

  3. apue.h头文件(UNIX环境高级编程)

    在看UNIX环境高级编程是,碰到一个头文件"apue.h",搜一下别人的帖子,其实apue.h是作者自己写的一个文件,包含了常用的头文件,系统不自带.其中包含了常用的头文件,以及出 ...

  4. 二、Mysql(二)

    原文参考:http://www.cnblogs.com/wupeiqi/articles/5713323.html 还有一个是课件,看着也像博客,但不知道是谁的 内置函数 触发器 存储过程 索引 与p ...

  5. CWnd *和HWnd转换

      CWnd *和HWnd转换 CWnd*得到HWnd CWnd    wnd;   HWND    hWnd; hWnd    =    wnd.m_hWnd;           //    or ...

  6. Eviews 9.0新版本新功能——预测(Auto-ARIMA预测、VAR预测)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 9.预测功能 新增需要方法的预测功能:Auto ...

  7. phpexcle 导出数据 日期格式的问题

    在使用phpexcle 读取excle中日期格式的出现了问题.特此记录 gmdate("Y-m-d H:i:s", PHPExcel_Shared_Date::ExcelToPHP ...

  8. HighCharts之2D含有负值的面积图

    HighCharts之2D含有负值的面积图 1.HighCharts之2D含有负值的面积图源码 AreaNegative.html: <!DOCTYPE html> <html> ...

  9. DirectX--yuv420p上实现的字符叠加

    unsigned char *pTemp; BYTE OsdY = 0;BYTE OsdU = 0;BYTE OsdV = 0; void OSDSetTextColor(BYTE OsdR, BYT ...

  10. FPGA 状态机设计

    数字系统有两大类有限状态机(Finite State Machine,FSM):Moore状态机和Mealy状态机. Moore状态机 其最大特点是输出只由当前状态确定,与输入无关.Moore状态机的 ...