【Java集合源码02】LinkedList源码分析

向右看齐 2022-12-26 04:49 267阅读 0赞

简介

LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:

  1. List list=Collections.synchronizedList(new LinkedList(...));

20201202170755.png

实现原理

双端链表

20201202194657.png

双端链表节点:

  1. private static class Node<E> {
  2. E item;
  3. Node<E> next;
  4. Node<E> prev;
  5. Node(Node<E> prev, E element, Node<E> next) {
  6. this.item = element;
  7. this.next = next;
  8. this.prev = prev;
  9. }
  10. }

源码解析

  1. public class LinkedList<E>
  2. extends AbstractSequentialList<E>
  3. implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  4. {
  5. transient int size = 0;
  6. /**
  7. * Pointer to first node.
  8. * Invariant: (first == null && last == null) ||
  9. * (first.prev == null && first.item != null)
  10. * 头结点
  11. */
  12. transient Node<E> first;
  13. /**
  14. * Pointer to last node.
  15. * Invariant: (first == null && last == null) ||
  16. * (last.next == null && last.item != null)
  17. * 尾结点
  18. */
  19. transient Node<E> last;
  20. /**
  21. * Constructs an empty list.
  22. * 无参构造函数
  23. */
  24. public LinkedList() {
  25. }
  26. /**
  27. * Constructs a list containing the elements of the specified
  28. * collection, in the order they are returned by the collection's
  29. * iterator.
  30. *
  31. * @param c the collection whose elements are to be placed into this list
  32. * @throws NullPointerException if the specified collection is null
  33. * 有参构造函数
  34. */
  35. public LinkedList(Collection<? extends E> c) {
  36. this();
  37. addAll(c);
  38. }
  39. /**
  40. * Links e as first element.
  41. * 把e设置为头结点
  42. */
  43. private void linkFirst(E e) {
  44. final Node<E> f = first;
  45. final Node<E> newNode = new Node<>(null, e, f);
  46. first = newNode;
  47. if (f == null)
  48. last = newNode;
  49. else
  50. f.prev = newNode;
  51. size++;
  52. modCount++;
  53. }
  54. /**
  55. * Links e as last element.
  56. * 把e设置为尾结点
  57. */
  58. void linkLast(E e) {
  59. final Node<E> l = last;
  60. final Node<E> newNode = new Node<>(l, e, null);
  61. last = newNode;
  62. if (l == null)
  63. first = newNode;
  64. else
  65. l.next = newNode;
  66. size++;
  67. modCount++;
  68. }
  69. /**
  70. * Inserts element e before non-null Node succ.
  71. * 插入一个结点e在succ之前
  72. */
  73. void linkBefore(E e, Node<E> succ) {
  74. // assert succ != null;
  75. final Node<E> pred = succ.prev;
  76. final Node<E> newNode = new Node<>(pred, e, succ);
  77. succ.prev = newNode;
  78. if (pred == null)
  79. first = newNode;
  80. else
  81. pred.next = newNode;
  82. size++;
  83. modCount++;
  84. }
  85. /**
  86. * Unlinks non-null first node f.
  87. 删除第一个结点
  88. */
  89. private E unlinkFirst(Node<E> f) {
  90. // assert f == first && f != null;
  91. final E element = f.item;
  92. final Node<E> next = f.next;
  93. f.item = null;
  94. f.next = null; // help GC
  95. first = next;
  96. if (next == null)
  97. last = null;
  98. else
  99. next.prev = null;
  100. size--;
  101. modCount++;
  102. return element;
  103. }
  104. /**
  105. * Unlinks non-null last node l.
  106. * 删除最后一个结点
  107. */
  108. private E unlinkLast(Node<E> l) {
  109. // assert l == last && l != null;
  110. final E element = l.item;
  111. final Node<E> prev = l.prev;
  112. l.item = null;
  113. l.prev = null; // help GC
  114. last = prev;
  115. if (prev == null)
  116. first = null;
  117. else
  118. prev.next = null;
  119. size--;
  120. modCount++;
  121. return element;
  122. }
  123. /**
  124. * Unlinks non-null node x.
  125. * 删除结点x
  126. */
  127. E unlink(Node<E> x) {
  128. // assert x != null;
  129. final E element = x.item;
  130. final Node<E> next = x.next;
  131. final Node<E> prev = x.prev;
  132. if (prev == null) {
  133. first = next;
  134. } else {
  135. prev.next = next;
  136. x.prev = null;
  137. }
  138. if (next == null) {
  139. last = prev;
  140. } else {
  141. next.prev = prev;
  142. x.next = null;
  143. }
  144. x.item = null;
  145. size--;
  146. modCount++;
  147. return element;
  148. }
  149. /**
  150. * Returns the first element in this list.
  151. *
  152. * @return the first element in this list
  153. * @throws NoSuchElementException if this list is empty
  154. * 返回头结点的值
  155. */
  156. public E getFirst() {
  157. final Node<E> f = first;
  158. if (f == null)
  159. throw new NoSuchElementException();
  160. return f.item;
  161. }
  162. /**
  163. * Returns the last element in this list.
  164. *
  165. * @return the last element in this list
  166. * @throws NoSuchElementException if this list is empty
  167. * 返回尾结点的值
  168. */
  169. public E getLast() {
  170. final Node<E> l = last;
  171. if (l == null)
  172. throw new NoSuchElementException();
  173. return l.item;
  174. }
  175. /**
  176. * Removes and returns the first element from this list.
  177. *
  178. * @return the first element from this list
  179. * @throws NoSuchElementException if this list is empty
  180. * 删除第一个结点并返回其值
  181. */
  182. public E removeFirst() {
  183. final Node<E> f = first;
  184. if (f == null)
  185. throw new NoSuchElementException();
  186. return unlinkFirst(f);
  187. }
  188. /**
  189. * Removes and returns the last element from this list.
  190. *
  191. * @return the last element from this list
  192. * @throws NoSuchElementException if this list is empty
  193. * 删除最后一个结点并返回其值
  194. */
  195. public E removeLast() {
  196. final Node<E> l = last;
  197. if (l == null)
  198. throw new NoSuchElementException();
  199. return unlinkLast(l);
  200. }
  201. /**
  202. * Inserts the specified element at the beginning of this list.
  203. *
  204. * @param e the element to add
  205. * 添加e结点作为首结点
  206. */
  207. public void addFirst(E e) {
  208. linkFirst(e);
  209. }
  210. /**
  211. * Appends the specified element to the end of this list.
  212. *
  213. * <p>This method is equivalent to {@link #add}.
  214. *
  215. * @param e the element to add
  216. * 添加e结点作为尾结点
  217. */
  218. public void addLast(E e) {
  219. linkLast(e);
  220. }
  221. /**
  222. * Returns {@code true} if this list contains the specified element.
  223. * More formally, returns {@code true} if and only if this list contains
  224. * at least one element {@code e} such that
  225. * <tt>(o==null ? e==null : o.equals(e))</tt>.
  226. *
  227. * @param o element whose presence in this list is to be tested
  228. * @return {@code true} if this list contains the specified element
  229. * 代码比较简单,不太想注释了,把上面几个看懂就可以了
  230. */
  231. public boolean contains(Object o) {
  232. return indexOf(o) != -1;
  233. }
  234. /**
  235. * Returns the number of elements in this list.
  236. *
  237. * @return the number of elements in this list
  238. */
  239. public int size() {
  240. return size;
  241. }
  242. /**
  243. * Appends the specified element to the end of this list.
  244. *
  245. * <p>This method is equivalent to {@link #addLast}.
  246. *
  247. * @param e element to be appended to this list
  248. * @return {@code true} (as specified by {@link Collection#add})
  249. */
  250. public boolean add(E e) {
  251. linkLast(e);
  252. return true;
  253. }
  254. /**
  255. * Removes the first occurrence of the specified element from this list,
  256. * if it is present. If this list does not contain the element, it is
  257. * unchanged. More formally, removes the element with the lowest index
  258. * {@code i} such that
  259. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
  260. * (if such an element exists). Returns {@code true} if this list
  261. * contained the specified element (or equivalently, if this list
  262. * changed as a result of the call).
  263. *
  264. * @param o element to be removed from this list, if present
  265. * @return {@code true} if this list contained the specified element
  266. */
  267. public boolean remove(Object o) {
  268. if (o == null) {
  269. for (Node<E> x = first; x != null; x = x.next) {
  270. if (x.item == null) {
  271. unlink(x);
  272. return true;
  273. }
  274. }
  275. } else {
  276. for (Node<E> x = first; x != null; x = x.next) {
  277. if (o.equals(x.item)) {
  278. unlink(x);
  279. return true;
  280. }
  281. }
  282. }
  283. return false;
  284. }
  285. /**
  286. * Appends all of the elements in the specified collection to the end of
  287. * this list, in the order that they are returned by the specified
  288. * collection's iterator. The behavior of this operation is undefined if
  289. * the specified collection is modified while the operation is in
  290. * progress. (Note that this will occur if the specified collection is
  291. * this list, and it's nonempty.)
  292. *
  293. * @param c collection containing elements to be added to this list
  294. * @return {@code true} if this list changed as a result of the call
  295. * @throws NullPointerException if the specified collection is null
  296. */
  297. public boolean addAll(Collection<? extends E> c) {
  298. return addAll(size, c);
  299. }
  300. /**
  301. * Inserts all of the elements in the specified collection into this
  302. * list, starting at the specified position. Shifts the element
  303. * currently at that position (if any) and any subsequent elements to
  304. * the right (increases their indices). The new elements will appear
  305. * in the list in the order that they are returned by the
  306. * specified collection's iterator.
  307. *
  308. * @param index index at which to insert the first element
  309. * from the specified collection
  310. * @param c collection containing elements to be added to this list
  311. * @return {@code true} if this list changed as a result of the call
  312. * @throws IndexOutOfBoundsException {@inheritDoc}
  313. * @throws NullPointerException if the specified collection is null
  314. */
  315. public boolean addAll(int index, Collection<? extends E> c) {
  316. checkPositionIndex(index);
  317. Object[] a = c.toArray();
  318. int numNew = a.length;
  319. if (numNew == 0)
  320. return false;
  321. // succ第index个结点,pred是succ的前驱结点
  322. Node<E> pred, succ;
  323. if (index == size) {
  324. succ = null;
  325. pred = last;
  326. } else {
  327. // 如果依次存入tom、jack、rose,第0个结点是tom,第2个结点是rose
  328. // node函数用于找到第index个结点
  329. succ = node(index);
  330. pred = succ.prev;
  331. }
  332. // 循环插入结点
  333. for (Object o : a) {
  334. @SuppressWarnings("unchecked") E e = (E) o;
  335. Node<E> newNode = new Node<>(pred, e, null);
  336. if (pred == null)
  337. first = newNode;
  338. else
  339. pred.next = newNode;
  340. pred = newNode;
  341. }
  342. if (succ == null) {
  343. last = pred;
  344. } else {
  345. pred.next = succ;
  346. succ.prev = pred;
  347. }
  348. size += numNew;
  349. modCount++;
  350. return true;
  351. }
  352. /**
  353. * Removes all of the elements from this list.
  354. * The list will be empty after this call returns.
  355. * 清空链表
  356. */
  357. public void clear() {
  358. // Clearing all of the links between nodes is "unnecessary", but:
  359. // - helps a generational GC if the discarded nodes inhabit
  360. // more than one generation
  361. // - is sure to free memory even if there is a reachable Iterator
  362. for (Node<E> x = first; x != null; ) {
  363. Node<E> next = x.next;
  364. x.item = null;
  365. x.next = null;
  366. x.prev = null;
  367. x = next;
  368. }
  369. first = last = null;
  370. size = 0;
  371. modCount++;
  372. }
  373. // Positional Access Operations
  374. /**
  375. * Returns the element at the specified position in this list.
  376. *
  377. * @param index index of the element to return
  378. * @return the element at the specified position in this list
  379. * @throws IndexOutOfBoundsException {@inheritDoc}
  380. */
  381. public E get(int index) {
  382. checkElementIndex(index);
  383. return node(index).item;
  384. }
  385. /**
  386. * Replaces the element at the specified position in this list with the
  387. * specified element.
  388. *
  389. * @param index index of the element to replace
  390. * @param element element to be stored at the specified position
  391. * @return the element previously at the specified position
  392. * @throws IndexOutOfBoundsException {@inheritDoc}
  393. */
  394. public E set(int index, E element) {
  395. checkElementIndex(index);
  396. Node<E> x = node(index);
  397. E oldVal = x.item;
  398. x.item = element;
  399. return oldVal;
  400. }
  401. /**
  402. * Inserts the specified element at the specified position in this list.
  403. * Shifts the element currently at that position (if any) and any
  404. * subsequent elements to the right (adds one to their indices).
  405. *
  406. * @param index index at which the specified element is to be inserted
  407. * @param element element to be inserted
  408. * @throws IndexOutOfBoundsException {@inheritDoc}
  409. */
  410. public void add(int index, E element) {
  411. checkPositionIndex(index);
  412. if (index == size)
  413. linkLast(element);
  414. else
  415. linkBefore(element, node(index));
  416. }
  417. /**
  418. * Removes the element at the specified position in this list. Shifts any
  419. * subsequent elements to the left (subtracts one from their indices).
  420. * Returns the element that was removed from the list.
  421. *
  422. * @param index the index of the element to be removed
  423. * @return the element previously at the specified position
  424. * @throws IndexOutOfBoundsException {@inheritDoc}
  425. */
  426. public E remove(int index) {
  427. checkElementIndex(index);
  428. return unlink(node(index));
  429. }
  430. /**
  431. * Tells if the argument is the index of an existing element.
  432. */
  433. private boolean isElementIndex(int index) {
  434. return index >= 0 && index < size;
  435. }
  436. /**
  437. * Tells if the argument is the index of a valid position for an
  438. * iterator or an add operation.
  439. * 判断插入位置index是否合法
  440. */
  441. private boolean isPositionIndex(int index) {
  442. return index >= 0 && index <= size;
  443. }
  444. /**
  445. * Constructs an IndexOutOfBoundsException detail message.
  446. * Of the many possible refactorings of the error handling code,
  447. * this "outlining" performs best with both server and client VMs.
  448. */
  449. private String outOfBoundsMsg(int index) {
  450. return "Index: "+index+", Size: "+size;
  451. }
  452. private void checkElementIndex(int index) {
  453. if (!isElementIndex(index))
  454. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  455. }
  456. private void checkPositionIndex(int index) {
  457. if (!isPositionIndex(index))
  458. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  459. }
  460. /**
  461. * Returns the (non-null) Node at the specified element index.
  462. */
  463. Node<E> node(int index) {
  464. // assert isElementIndex(index);
  465. // 这里用点小技巧,index < size / 2,说明index在前半段,否则index在后半段
  466. if (index < (size >> 1)) {
  467. Node<E> x = first;
  468. for (int i = 0; i < index; i++)
  469. x = x.next;
  470. return x;
  471. } else {
  472. Node<E> x = last;
  473. for (int i = size - 1; i > index; i--)
  474. x = x.prev;
  475. return x;
  476. }
  477. }
  478. // Search Operations
  479. /**
  480. * Returns the index of the first occurrence of the specified element
  481. * in this list, or -1 if this list does not contain the element.
  482. * More formally, returns the lowest index {@code i} such that
  483. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
  484. * or -1 if there is no such index.
  485. *
  486. * @param o element to search for
  487. * @return the index of the first occurrence of the specified element in
  488. * this list, or -1 if this list does not contain the element
  489. */
  490. public int indexOf(Object o) {
  491. int index = 0;
  492. if (o == null) {
  493. for (Node<E> x = first; x != null; x = x.next) {
  494. if (x.item == null)
  495. return index;
  496. index++;
  497. }
  498. } else {
  499. for (Node<E> x = first; x != null; x = x.next) {
  500. if (o.equals(x.item))
  501. return index;
  502. index++;
  503. }
  504. }
  505. return -1;
  506. }
  507. /**
  508. * Returns the index of the last occurrence of the specified element
  509. * in this list, or -1 if this list does not contain the element.
  510. * More formally, returns the highest index {@code i} such that
  511. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
  512. * or -1 if there is no such index.
  513. *
  514. * @param o element to search for
  515. * @return the index of the last occurrence of the specified element in
  516. * this list, or -1 if this list does not contain the element
  517. * 返回最后出现o的位置,也就是出现o,index最大的位置
  518. */
  519. public int lastIndexOf(Object o) {
  520. int index = size;
  521. // 逆向遍历
  522. if (o == null) {
  523. for (Node<E> x = last; x != null; x = x.prev) {
  524. index--;
  525. if (x.item == null)
  526. return index;
  527. }
  528. } else {
  529. for (Node<E> x = last; x != null; x = x.prev) {
  530. index--;
  531. if (o.equals(x.item))
  532. return index;
  533. }
  534. }
  535. return -1;
  536. }
  537. // Queue operations.
  538. /**
  539. * Retrieves, but does not remove, the head (first element) of this list.
  540. *
  541. * @return the head of this list, or {@code null} if this list is empty
  542. * @since 1.5
  543. */
  544. public E peek() {
  545. final Node<E> f = first;
  546. return (f == null) ? null : f.item;
  547. }
  548. /**
  549. * Retrieves, but does not remove, the head (first element) of this list.
  550. *
  551. * @return the head of this list
  552. * @throws NoSuchElementException if this list is empty
  553. * @since 1.5
  554. */
  555. public E element() {
  556. return getFirst();
  557. }
  558. /**
  559. * Retrieves and removes the head (first element) of this list.
  560. *
  561. * @return the head of this list, or {@code null} if this list is empty
  562. * @since 1.5
  563. */
  564. public E poll() {
  565. final Node<E> f = first;
  566. return (f == null) ? null : unlinkFirst(f);
  567. }
  568. /**
  569. * Retrieves and removes the head (first element) of this list.
  570. *
  571. * @return the head of this list
  572. * @throws NoSuchElementException if this list is empty
  573. * @since 1.5
  574. */
  575. public E remove() {
  576. return removeFirst();
  577. }
  578. /**
  579. * Adds the specified element as the tail (last element) of this list.
  580. *
  581. * @param e the element to add
  582. * @return {@code true} (as specified by {@link Queue#offer})
  583. * @since 1.5
  584. */
  585. public boolean offer(E e) {
  586. return add(e);
  587. }
  588. // Deque operations
  589. /**
  590. * Inserts the specified element at the front of this list.
  591. *
  592. * @param e the element to insert
  593. * @return {@code true} (as specified by {@link Deque#offerFirst})
  594. * @since 1.6
  595. */
  596. public boolean offerFirst(E e) {
  597. addFirst(e);
  598. return true;
  599. }
  600. /**
  601. * Inserts the specified element at the end of this list.
  602. *
  603. * @param e the element to insert
  604. * @return {@code true} (as specified by {@link Deque#offerLast})
  605. * @since 1.6
  606. */
  607. public boolean offerLast(E e) {
  608. addLast(e);
  609. return true;
  610. }
  611. /**
  612. * Retrieves, but does not remove, the first element of this list,
  613. * or returns {@code null} if this list is empty.
  614. *
  615. * @return the first element of this list, or {@code null}
  616. * if this list is empty
  617. * @since 1.6
  618. */
  619. public E peekFirst() {
  620. final Node<E> f = first;
  621. return (f == null) ? null : f.item;
  622. }
  623. /**
  624. * Retrieves, but does not remove, the last element of this list,
  625. * or returns {@code null} if this list is empty.
  626. *
  627. * @return the last element of this list, or {@code null}
  628. * if this list is empty
  629. * @since 1.6
  630. */
  631. public E peekLast() {
  632. final Node<E> l = last;
  633. return (l == null) ? null : l.item;
  634. }
  635. /**
  636. * Retrieves and removes the first element of this list,
  637. * or returns {@code null} if this list is empty.
  638. *
  639. * @return the first element of this list, or {@code null} if
  640. * this list is empty
  641. * @since 1.6
  642. */
  643. public E pollFirst() {
  644. final Node<E> f = first;
  645. return (f == null) ? null : unlinkFirst(f);
  646. }
  647. /**
  648. * Retrieves and removes the last element of this list,
  649. * or returns {@code null} if this list is empty.
  650. *
  651. * @return the last element of this list, or {@code null} if
  652. * this list is empty
  653. * @since 1.6
  654. */
  655. public E pollLast() {
  656. final Node<E> l = last;
  657. return (l == null) ? null : unlinkLast(l);
  658. }
  659. /**
  660. * Pushes an element onto the stack represented by this list. In other
  661. * words, inserts the element at the front of this list.
  662. *
  663. * <p>This method is equivalent to {@link #addFirst}.
  664. *
  665. * @param e the element to push
  666. * @since 1.6
  667. */
  668. public void push(E e) {
  669. addFirst(e);
  670. }
  671. /**
  672. * Pops an element from the stack represented by this list. In other
  673. * words, removes and returns the first element of this list.
  674. *
  675. * <p>This method is equivalent to {@link #removeFirst()}.
  676. *
  677. * @return the element at the front of this list (which is the top
  678. * of the stack represented by this list)
  679. * @throws NoSuchElementException if this list is empty
  680. * @since 1.6
  681. */
  682. public E pop() {
  683. return removeFirst();
  684. }
  685. /**
  686. * Removes the first occurrence of the specified element in this
  687. * list (when traversing the list from head to tail). If the list
  688. * does not contain the element, it is unchanged.
  689. *
  690. * @param o element to be removed from this list, if present
  691. * @return {@code true} if the list contained the specified element
  692. * @since 1.6
  693. */
  694. public boolean removeFirstOccurrence(Object o) {
  695. return remove(o);
  696. }
  697. /**
  698. * Removes the last occurrence of the specified element in this
  699. * list (when traversing the list from head to tail). If the list
  700. * does not contain the element, it is unchanged.
  701. *
  702. * @param o element to be removed from this list, if present
  703. * @return {@code true} if the list contained the specified element
  704. * @since 1.6
  705. */
  706. public boolean removeLastOccurrence(Object o) {
  707. if (o == null) {
  708. for (Node<E> x = last; x != null; x = x.prev) {
  709. if (x.item == null) {
  710. unlink(x);
  711. return true;
  712. }
  713. }
  714. } else {
  715. for (Node<E> x = last; x != null; x = x.prev) {
  716. if (o.equals(x.item)) {
  717. unlink(x);
  718. return true;
  719. }
  720. }
  721. }
  722. return false;
  723. }
  724. /**
  725. * Returns a list-iterator of the elements in this list (in proper
  726. * sequence), starting at the specified position in the list.
  727. * Obeys the general contract of {@code List.listIterator(int)}.<p>
  728. *
  729. * The list-iterator is <i>fail-fast</i>: if the list is structurally
  730. * modified at any time after the Iterator is created, in any way except
  731. * through the list-iterator's own {@code remove} or {@code add}
  732. * methods, the list-iterator will throw a
  733. * {@code ConcurrentModificationException}. Thus, in the face of
  734. * concurrent modification, the iterator fails quickly and cleanly, rather
  735. * than risking arbitrary, non-deterministic behavior at an undetermined
  736. * time in the future.
  737. *
  738. * @param index index of the first element to be returned from the
  739. * list-iterator (by a call to {@code next})
  740. * @return a ListIterator of the elements in this list (in proper
  741. * sequence), starting at the specified position in the list
  742. * @throws IndexOutOfBoundsException {@inheritDoc}
  743. * @see List#listIterator(int)
  744. */
  745. public ListIterator<E> listIterator(int index) {
  746. checkPositionIndex(index);
  747. return new ListItr(index);
  748. }
  749. private class ListItr implements ListIterator<E> {
  750. private Node<E> lastReturned;
  751. private Node<E> next;
  752. private int nextIndex;
  753. private int expectedModCount = modCount;
  754. ListItr(int index) {
  755. // assert isPositionIndex(index);
  756. next = (index == size) ? null : node(index);
  757. nextIndex = index;
  758. }
  759. public boolean hasNext() {
  760. return nextIndex < size;
  761. }
  762. public E next() {
  763. checkForComodification();
  764. if (!hasNext())
  765. throw new NoSuchElementException();
  766. lastReturned = next;
  767. next = next.next;
  768. nextIndex++;
  769. return lastReturned.item;
  770. }
  771. public boolean hasPrevious() {
  772. return nextIndex > 0;
  773. }
  774. public E previous() {
  775. checkForComodification();
  776. if (!hasPrevious())
  777. throw new NoSuchElementException();
  778. lastReturned = next = (next == null) ? last : next.prev;
  779. nextIndex--;
  780. return lastReturned.item;
  781. }
  782. public int nextIndex() {
  783. return nextIndex;
  784. }
  785. public int previousIndex() {
  786. return nextIndex - 1;
  787. }
  788. public void remove() {
  789. checkForComodification();
  790. if (lastReturned == null)
  791. throw new IllegalStateException();
  792. Node<E> lastNext = lastReturned.next;
  793. unlink(lastReturned);
  794. if (next == lastReturned)
  795. next = lastNext;
  796. else
  797. nextIndex--;
  798. lastReturned = null;
  799. expectedModCount++;
  800. }
  801. public void set(E e) {
  802. if (lastReturned == null)
  803. throw new IllegalStateException();
  804. checkForComodification();
  805. lastReturned.item = e;
  806. }
  807. public void add(E e) {
  808. checkForComodification();
  809. lastReturned = null;
  810. if (next == null)
  811. linkLast(e);
  812. else
  813. linkBefore(e, next);
  814. nextIndex++;
  815. expectedModCount++;
  816. }
  817. public void forEachRemaining(Consumer<? super E> action) {
  818. Objects.requireNonNull(action);
  819. while (modCount == expectedModCount && nextIndex < size) {
  820. action.accept(next.item);
  821. lastReturned = next;
  822. next = next.next;
  823. nextIndex++;
  824. }
  825. checkForComodification();
  826. }
  827. final void checkForComodification() {
  828. if (modCount != expectedModCount)
  829. throw new ConcurrentModificationException();
  830. }
  831. }
  832. private static class Node<E> {
  833. E item;
  834. Node<E> next;
  835. Node<E> prev;
  836. Node(Node<E> prev, E element, Node<E> next) {
  837. this.item = element;
  838. this.next = next;
  839. this.prev = prev;
  840. }
  841. }
  842. /**
  843. * @since 1.6
  844. */
  845. public Iterator<E> descendingIterator() {
  846. return new DescendingIterator();
  847. }
  848. /**
  849. * Adapter to provide descending iterators via ListItr.previous
  850. */
  851. private class DescendingIterator implements Iterator<E> {
  852. private final ListItr itr = new ListItr(size());
  853. public boolean hasNext() {
  854. return itr.hasPrevious();
  855. }
  856. public E next() {
  857. return itr.previous();
  858. }
  859. public void remove() {
  860. itr.remove();
  861. }
  862. }
  863. @SuppressWarnings("unchecked")
  864. private LinkedList<E> superClone() {
  865. try {
  866. return (LinkedList<E>) super.clone();
  867. } catch (CloneNotSupportedException e) {
  868. throw new InternalError(e);
  869. }
  870. }
  871. /**
  872. * Returns a shallow copy of this {@code LinkedList}. (The elements
  873. * themselves are not cloned.)
  874. *
  875. * @return a shallow copy of this {@code LinkedList} instance
  876. */
  877. public Object clone() {
  878. LinkedList<E> clone = superClone();
  879. // Put clone into "virgin" state
  880. clone.first = clone.last = null;
  881. clone.size = 0;
  882. clone.modCount = 0;
  883. // Initialize clone with our elements
  884. for (Node<E> x = first; x != null; x = x.next)
  885. clone.add(x.item);
  886. return clone;
  887. }
  888. /**
  889. * Returns an array containing all of the elements in this list
  890. * in proper sequence (from first to last element).
  891. *
  892. * <p>The returned array will be "safe" in that no references to it are
  893. * maintained by this list. (In other words, this method must allocate
  894. * a new array). The caller is thus free to modify the returned array.
  895. *
  896. * <p>This method acts as bridge between array-based and collection-based
  897. * APIs.
  898. *
  899. * @return an array containing all of the elements in this list
  900. * in proper sequence
  901. */
  902. public Object[] toArray() {
  903. Object[] result = new Object[size];
  904. int i = 0;
  905. for (Node<E> x = first; x != null; x = x.next)
  906. result[i++] = x.item;
  907. return result;
  908. }
  909. /**
  910. * Returns an array containing all of the elements in this list in
  911. * proper sequence (from first to last element); the runtime type of
  912. * the returned array is that of the specified array. If the list fits
  913. * in the specified array, it is returned therein. Otherwise, a new
  914. * array is allocated with the runtime type of the specified array and
  915. * the size of this list.
  916. *
  917. * <p>If the list fits in the specified array with room to spare (i.e.,
  918. * the array has more elements than the list), the element in the array
  919. * immediately following the end of the list is set to {@code null}.
  920. * (This is useful in determining the length of the list <i>only</i> if
  921. * the caller knows that the list does not contain any null elements.)
  922. *
  923. * <p>Like the {@link #toArray()} method, this method acts as bridge between
  924. * array-based and collection-based APIs. Further, this method allows
  925. * precise control over the runtime type of the output array, and may,
  926. * under certain circumstances, be used to save allocation costs.
  927. *
  928. * <p>Suppose {@code x} is a list known to contain only strings.
  929. * The following code can be used to dump the list into a newly
  930. * allocated array of {@code String}:
  931. *
  932. * <pre>
  933. * String[] y = x.toArray(new String[0]);</pre>
  934. *
  935. * Note that {@code toArray(new Object[0])} is identical in function to
  936. * {@code toArray()}.
  937. *
  938. * @param a the array into which the elements of the list are to
  939. * be stored, if it is big enough; otherwise, a new array of the
  940. * same runtime type is allocated for this purpose.
  941. * @return an array containing the elements of the list
  942. * @throws ArrayStoreException if the runtime type of the specified array
  943. * is not a supertype of the runtime type of every element in
  944. * this list
  945. * @throws NullPointerException if the specified array is null
  946. */
  947. @SuppressWarnings("unchecked")
  948. public <T> T[] toArray(T[] a) {
  949. if (a.length < size)
  950. a = (T[])java.lang.reflect.Array.newInstance(
  951. a.getClass().getComponentType(), size);
  952. int i = 0;
  953. Object[] result = a;
  954. for (Node<E> x = first; x != null; x = x.next)
  955. result[i++] = x.item;
  956. if (a.length > size)
  957. a[size] = null;
  958. return a;
  959. }
  960. private static final long serialVersionUID = 876323262645176354L;
  961. }

推荐阅读

  • 机器学习资料汇总
  • 吴恩达《机器学习》视频、作业、源码
  • 106页《Python进阶》中文版正式发布
  • 李航《统计学习方法》第二版完整课件
  • 机器学习数学全书,1900页PDF下载

gzh.jpg

发表评论

表情:
评论列表 (有 0 条评论,267人围观)

还没有评论,来说两句吧...

相关阅读