LinkedList源码分析

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

从源码中我们知道:
1.LinkedList是线程不安全的,只适合在单线程中使用;
2.LinkedList 底层是用双向链表实现的;所以进行遍历时用迭代器快一些;
3.如果牵扯到大量元素频繁的进行插入和删除,用LinkedList,因为它只是对于指针的改变,不像ArrayList是对元素的复制,所以快。

发表评论

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

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

相关阅读