1. /*
  2. * @(#)LinkedList.java 1.46 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. /**
  9. * Linked list implementation of the <tt>List</tt> interface. Implements all
  10. * optional list operations, and permits all elements (including
  11. * <tt>null</tt>). In addition to implementing the <tt>List</tt> interface,
  12. * the <tt>LinkedList</tt> class provides uniformly named methods to
  13. * <tt>get</tt>, <tt>remove</tt> and <tt>insert</tt> an element at the
  14. * beginning and end of the list. These operations allow linked lists to be
  15. * used as a stack, queue, or double-ended queue (deque).<p>
  16. *
  17. * All of the stack/queue/deque operations could be easily recast in terms of
  18. * the standard list operations. They're included here primarily for
  19. * convenience, though they may run slightly faster than the equivalent List
  20. * operations.<p>
  21. *
  22. * All of the operations perform as could be expected for a doubly-linked
  23. * list. Operations that index into the list will traverse the list from
  24. * the begining or the end, whichever is closer to the specified index.<p>
  25. *
  26. * <b>Note that this implementation is not synchronized.</b> If multiple
  27. * threads access a list concurrently, and at least one of the threads
  28. * modifies the list structurally, it <i>must</i> be synchronized
  29. * externally. (A structural modification is any operation that adds or
  30. * deletes one or more elements; merely setting the value of an element is not
  31. * a structural modification.) This is typically accomplished by
  32. * synchronizing on some object that naturally encapsulates the list. If no
  33. * such object exists, the list should be "wrapped" using the
  34. * Collections.synchronizedList method. This is best done at creation time,
  35. * to prevent accidental unsynchronized access to the list: <pre>
  36. * List list = Collections.synchronizedList(new LinkedList(...));
  37. * </pre><p>
  38. *
  39. * The iterators returned by the this class's <tt>iterator</tt> and
  40. * <tt>listIterator</tt> methods are <i>fail-fast</i>: if the list is
  41. * structurally modified at any time after the iterator is created, in any way
  42. * except through the Iterator's own <tt>remove</tt> or <tt>add</tt> methods,
  43. * the iterator will throw a <tt>ConcurrentModificationException</tt>. Thus,
  44. * in the face of concurrent modification, the iterator fails quickly and
  45. * cleanly, rather than risking arbitrary, non-deterministic behavior at an
  46. * undetermined time in the future.
  47. *
  48. * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  49. * as it is, generally speaking, impossible to make any hard guarantees in the
  50. * presence of unsynchronized concurrent modification. Fail-fast iterators
  51. * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  52. * Therefore, it would be wrong to write a program that depended on this
  53. * exception for its correctness: <i>the fail-fast behavior of iterators
  54. * should be used only to detect bugs.</i><p>
  55. *
  56. * This class is a member of the
  57. * <a href="{@docRoot}/../guide/collections/index.html">
  58. * Java Collections Framework</a>.
  59. *
  60. * @author Josh Bloch
  61. * @version 1.46, 01/23/03
  62. * @see List
  63. * @see ArrayList
  64. * @see Vector
  65. * @see Collections#synchronizedList(List)
  66. * @since 1.2
  67. */
  68. public class LinkedList extends AbstractSequentialList
  69. implements List, Cloneable, java.io.Serializable
  70. {
  71. private transient Entry header = new Entry(null, null, null);
  72. private transient int size = 0;
  73. /**
  74. * Constructs an empty list.
  75. */
  76. public LinkedList() {
  77. header.next = header.previous = header;
  78. }
  79. /**
  80. * Constructs a list containing the elements of the specified
  81. * collection, in the order they are returned by the collection's
  82. * iterator.
  83. *
  84. * @param c the collection whose elements are to be placed into this list.
  85. * @throws NullPointerException if the specified collection is null.
  86. */
  87. public LinkedList(Collection c) {
  88. this();
  89. addAll(c);
  90. }
  91. /**
  92. * Returns the first element in this list.
  93. *
  94. * @return the first element in this list.
  95. * @throws NoSuchElementException if this list is empty.
  96. */
  97. public Object getFirst() {
  98. if (size==0)
  99. throw new NoSuchElementException();
  100. return header.next.element;
  101. }
  102. /**
  103. * Returns the last element in this list.
  104. *
  105. * @return the last element in this list.
  106. * @throws NoSuchElementException if this list is empty.
  107. */
  108. public Object getLast() {
  109. if (size==0)
  110. throw new NoSuchElementException();
  111. return header.previous.element;
  112. }
  113. /**
  114. * Removes and returns the first element from this list.
  115. *
  116. * @return the first element from this list.
  117. * @throws NoSuchElementException if this list is empty.
  118. */
  119. public Object removeFirst() {
  120. Object first = header.next.element;
  121. remove(header.next);
  122. return first;
  123. }
  124. /**
  125. * Removes and returns the last element from this list.
  126. *
  127. * @return the last element from this list.
  128. * @throws NoSuchElementException if this list is empty.
  129. */
  130. public Object removeLast() {
  131. Object last = header.previous.element;
  132. remove(header.previous);
  133. return last;
  134. }
  135. /**
  136. * Inserts the given element at the beginning of this list.
  137. *
  138. * @param o the element to be inserted at the beginning of this list.
  139. */
  140. public void addFirst(Object o) {
  141. addBefore(o, header.next);
  142. }
  143. /**
  144. * Appends the given element to the end of this list. (Identical in
  145. * function to the <tt>add</tt> method; included only for consistency.)
  146. *
  147. * @param o the element to be inserted at the end of this list.
  148. */
  149. public void addLast(Object o) {
  150. addBefore(o, header);
  151. }
  152. /**
  153. * Returns <tt>true</tt> if this list contains the specified element.
  154. * More formally, returns <tt>true</tt> if and only if this list contains
  155. * at least one element <tt>e</tt> such that <tt>(o==null ? e==null
  156. * : o.equals(e))</tt>.
  157. *
  158. * @param o element whose presence in this list is to be tested.
  159. * @return <tt>true</tt> if this list contains the specified element.
  160. */
  161. public boolean contains(Object o) {
  162. return indexOf(o) != -1;
  163. }
  164. /**
  165. * Returns the number of elements in this list.
  166. *
  167. * @return the number of elements in this list.
  168. */
  169. public int size() {
  170. return size;
  171. }
  172. /**
  173. * Appends the specified element to the end of this list.
  174. *
  175. * @param o element to be appended to this list.
  176. * @return <tt>true</tt> (as per the general contract of
  177. * <tt>Collection.add</tt>).
  178. */
  179. public boolean add(Object o) {
  180. addBefore(o, header);
  181. return true;
  182. }
  183. /**
  184. * Removes the first occurrence of the specified element in this list. If
  185. * the list does not contain the element, it is unchanged. More formally,
  186. * removes the element with the lowest index <tt>i</tt> such that
  187. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt> (if such an
  188. * element exists).
  189. *
  190. * @param o element to be removed from this list, if present.
  191. * @return <tt>true</tt> if the list contained the specified element.
  192. */
  193. public boolean remove(Object o) {
  194. if (o==null) {
  195. for (Entry e = header.next; e != header; e = e.next) {
  196. if (e.element==null) {
  197. remove(e);
  198. return true;
  199. }
  200. }
  201. } else {
  202. for (Entry e = header.next; e != header; e = e.next) {
  203. if (o.equals(e.element)) {
  204. remove(e);
  205. return true;
  206. }
  207. }
  208. }
  209. return false;
  210. }
  211. /**
  212. * Appends all of the elements in the specified collection to the end of
  213. * this list, in the order that they are returned by the specified
  214. * collection's iterator. The behavior of this operation is undefined if
  215. * the specified collection is modified while the operation is in
  216. * progress. (This implies that the behavior of this call is undefined if
  217. * the specified Collection is this list, and this list is nonempty.)
  218. *
  219. * @param c the elements to be inserted into this list.
  220. * @return <tt>true</tt> if this list changed as a result of the call.
  221. * @throws NullPointerException if the specified collection is null.
  222. */
  223. public boolean addAll(Collection c) {
  224. return addAll(size, c);
  225. }
  226. /**
  227. * Inserts all of the elements in the specified collection into this
  228. * list, starting at the specified position. Shifts the element
  229. * currently at that position (if any) and any subsequent elements to
  230. * the right (increases their indices). The new elements will appear
  231. * in the list in the order that they are returned by the
  232. * specified collection's iterator.
  233. *
  234. * @param index index at which to insert first element
  235. * from the specified collection.
  236. * @param c elements to be inserted into this list.
  237. * @return <tt>true</tt> if this list changed as a result of the call.
  238. * @throws IndexOutOfBoundsException if the specified index is out of
  239. * range (<tt>index < 0 || index > size()</tt>).
  240. * @throws NullPointerException if the specified collection is null.
  241. */
  242. public boolean addAll(int index, Collection c) {
  243. Object[] a = c.toArray();
  244. int numNew = a.length;
  245. if (numNew==0)
  246. return false;
  247. modCount++;
  248. Entry successor = (index==size ? header : entry(index));
  249. Entry predecessor = successor.previous;
  250. for (int i=0; i<numNew; i++) {
  251. Entry e = new Entry(a[i], successor, predecessor);
  252. predecessor.next = e;
  253. predecessor = e;
  254. }
  255. successor.previous = predecessor;
  256. size += numNew;
  257. return true;
  258. }
  259. /**
  260. * Removes all of the elements from this list.
  261. */
  262. public void clear() {
  263. modCount++;
  264. header.next = header.previous = header;
  265. size = 0;
  266. }
  267. // Positional Access Operations
  268. /**
  269. * Returns the element at the specified position in this list.
  270. *
  271. * @param index index of element to return.
  272. * @return the element at the specified position in this list.
  273. *
  274. * @throws IndexOutOfBoundsException if the specified index is is out of
  275. * range (<tt>index < 0 || index >= size()</tt>).
  276. */
  277. public Object get(int index) {
  278. return entry(index).element;
  279. }
  280. /**
  281. * Replaces the element at the specified position in this list with the
  282. * specified element.
  283. *
  284. * @param index index of element to replace.
  285. * @param element element to be stored at the specified position.
  286. * @return the element previously at the specified position.
  287. * @throws IndexOutOfBoundsException if the specified index is out of
  288. * range (<tt>index < 0 || index >= size()</tt>).
  289. */
  290. public Object set(int index, Object element) {
  291. Entry e = entry(index);
  292. Object oldVal = e.element;
  293. e.element = element;
  294. return oldVal;
  295. }
  296. /**
  297. * Inserts the specified element at the specified position in this list.
  298. * Shifts the element currently at that position (if any) and any
  299. * subsequent elements to the right (adds one to their indices).
  300. *
  301. * @param index index at which the specified element is to be inserted.
  302. * @param element element to be inserted.
  303. *
  304. * @throws IndexOutOfBoundsException if the specified index is out of
  305. * range (<tt>index < 0 || index > size()</tt>).
  306. */
  307. public void add(int index, Object element) {
  308. addBefore(element, (index==size ? header : entry(index)));
  309. }
  310. /**
  311. * Removes the element at the specified position in this list. Shifts any
  312. * subsequent elements to the left (subtracts one from their indices).
  313. * Returns the element that was removed from the list.
  314. *
  315. * @param index the index of the element to removed.
  316. * @return the element previously at the specified position.
  317. *
  318. * @throws IndexOutOfBoundsException if the specified index is out of
  319. * range (<tt>index < 0 || index >= size()</tt>).
  320. */
  321. public Object remove(int index) {
  322. Entry e = entry(index);
  323. remove(e);
  324. return e.element;
  325. }
  326. /**
  327. * Return the indexed entry.
  328. */
  329. private Entry entry(int index) {
  330. if (index < 0 || index >= size)
  331. throw new IndexOutOfBoundsException("Index: "+index+
  332. ", Size: "+size);
  333. Entry e = header;
  334. if (index < (size >> 1)) {
  335. for (int i = 0; i <= index; i++)
  336. e = e.next;
  337. } else {
  338. for (int i = size; i > index; i--)
  339. e = e.previous;
  340. }
  341. return e;
  342. }
  343. // Search Operations
  344. /**
  345. * Returns the index in this list of the first occurrence of the
  346. * specified element, or -1 if the List does not contain this
  347. * element. More formally, returns the lowest index i such that
  348. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, or -1 if
  349. * there is no such index.
  350. *
  351. * @param o element to search for.
  352. * @return the index in this list of the first occurrence of the
  353. * specified element, or -1 if the list does not contain this
  354. * element.
  355. */
  356. public int indexOf(Object o) {
  357. int index = 0;
  358. if (o==null) {
  359. for (Entry e = header.next; e != header; e = e.next) {
  360. if (e.element==null)
  361. return index;
  362. index++;
  363. }
  364. } else {
  365. for (Entry e = header.next; e != header; e = e.next) {
  366. if (o.equals(e.element))
  367. return index;
  368. index++;
  369. }
  370. }
  371. return -1;
  372. }
  373. /**
  374. * Returns the index in this list of the last occurrence of the
  375. * specified element, or -1 if the list does not contain this
  376. * element. More formally, returns the highest index i such that
  377. * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, or -1 if
  378. * there is no such index.
  379. *
  380. * @param o element to search for.
  381. * @return the index in this list of the last occurrence of the
  382. * specified element, or -1 if the list does not contain this
  383. * element.
  384. */
  385. public int lastIndexOf(Object o) {
  386. int index = size;
  387. if (o==null) {
  388. for (Entry e = header.previous; e != header; e = e.previous) {
  389. index--;
  390. if (e.element==null)
  391. return index;
  392. }
  393. } else {
  394. for (Entry e = header.previous; e != header; e = e.previous) {
  395. index--;
  396. if (o.equals(e.element))
  397. return index;
  398. }
  399. }
  400. return -1;
  401. }
  402. /**
  403. * Returns a list-iterator of the elements in this list (in proper
  404. * sequence), starting at the specified position in the list.
  405. * Obeys the general contract of <tt>List.listIterator(int)</tt>.<p>
  406. *
  407. * The list-iterator is <i>fail-fast</i>: if the list is structurally
  408. * modified at any time after the Iterator is created, in any way except
  409. * through the list-iterator's own <tt>remove</tt> or <tt>add</tt>
  410. * methods, the list-iterator will throw a
  411. * <tt>ConcurrentModificationException</tt>. Thus, in the face of
  412. * concurrent modification, the iterator fails quickly and cleanly, rather
  413. * than risking arbitrary, non-deterministic behavior at an undetermined
  414. * time in the future.
  415. *
  416. * @param index index of first element to be returned from the
  417. * list-iterator (by a call to <tt>next</tt>).
  418. * @return a ListIterator of the elements in this list (in proper
  419. * sequence), starting at the specified position in the list.
  420. * @throws IndexOutOfBoundsException if index is out of range
  421. * (<tt>index < 0 || index > size()</tt>).
  422. * @see List#listIterator(int)
  423. */
  424. public ListIterator listIterator(int index) {
  425. return new ListItr(index);
  426. }
  427. private class ListItr implements ListIterator {
  428. private Entry lastReturned = header;
  429. private Entry next;
  430. private int nextIndex;
  431. private int expectedModCount = modCount;
  432. ListItr(int index) {
  433. if (index < 0 || index > size)
  434. throw new IndexOutOfBoundsException("Index: "+index+
  435. ", Size: "+size);
  436. if (index < (size >> 1)) {
  437. next = header.next;
  438. for (nextIndex=0; nextIndex<index; nextIndex++)
  439. next = next.next;
  440. } else {
  441. next = header;
  442. for (nextIndex=size; nextIndex>index; nextIndex--)
  443. next = next.previous;
  444. }
  445. }
  446. public boolean hasNext() {
  447. return nextIndex != size;
  448. }
  449. public Object next() {
  450. checkForComodification();
  451. if (nextIndex == size)
  452. throw new NoSuchElementException();
  453. lastReturned = next;
  454. next = next.next;
  455. nextIndex++;
  456. return lastReturned.element;
  457. }
  458. public boolean hasPrevious() {
  459. return nextIndex != 0;
  460. }
  461. public Object previous() {
  462. if (nextIndex == 0)
  463. throw new NoSuchElementException();
  464. lastReturned = next = next.previous;
  465. nextIndex--;
  466. checkForComodification();
  467. return lastReturned.element;
  468. }
  469. public int nextIndex() {
  470. return nextIndex;
  471. }
  472. public int previousIndex() {
  473. return nextIndex-1;
  474. }
  475. public void remove() {
  476. checkForComodification();
  477. try {
  478. LinkedList.this.remove(lastReturned);
  479. } catch (NoSuchElementException e) {
  480. throw new IllegalStateException();
  481. }
  482. if (next==lastReturned)
  483. next = lastReturned.next;
  484. else
  485. nextIndex--;
  486. lastReturned = header;
  487. expectedModCount++;
  488. }
  489. public void set(Object o) {
  490. if (lastReturned == header)
  491. throw new IllegalStateException();
  492. checkForComodification();
  493. lastReturned.element = o;
  494. }
  495. public void add(Object o) {
  496. checkForComodification();
  497. lastReturned = header;
  498. addBefore(o, next);
  499. nextIndex++;
  500. expectedModCount++;
  501. }
  502. final void checkForComodification() {
  503. if (modCount != expectedModCount)
  504. throw new ConcurrentModificationException();
  505. }
  506. }
  507. private static class Entry {
  508. Object element;
  509. Entry next;
  510. Entry previous;
  511. Entry(Object element, Entry next, Entry previous) {
  512. this.element = element;
  513. this.next = next;
  514. this.previous = previous;
  515. }
  516. }
  517. private Entry addBefore(Object o, Entry e) {
  518. Entry newEntry = new Entry(o, e, e.previous);
  519. newEntry.previous.next = newEntry;
  520. newEntry.next.previous = newEntry;
  521. size++;
  522. modCount++;
  523. return newEntry;
  524. }
  525. private void remove(Entry e) {
  526. if (e == header)
  527. throw new NoSuchElementException();
  528. e.previous.next = e.next;
  529. e.next.previous = e.previous;
  530. size--;
  531. modCount++;
  532. }
  533. /**
  534. * Returns a shallow copy of this <tt>LinkedList</tt>. (The elements
  535. * themselves are not cloned.)
  536. *
  537. * @return a shallow copy of this <tt>LinkedList</tt> instance.
  538. */
  539. public Object clone() {
  540. LinkedList clone = null;
  541. try {
  542. clone = (LinkedList)super.clone();
  543. } catch (CloneNotSupportedException e) {
  544. throw new InternalError();
  545. }
  546. // Put clone into "virgin" state
  547. clone.header = new Entry(null, null, null);
  548. clone.header.next = clone.header.previous = clone.header;
  549. clone.size = 0;
  550. clone.modCount = 0;
  551. // Initialize clone with our elements
  552. for (Entry e = header.next; e != header; e = e.next)
  553. clone.add(e.element);
  554. return clone;
  555. }
  556. /**
  557. * Returns an array containing all of the elements in this list
  558. * in the correct order.
  559. *
  560. * @return an array containing all of the elements in this list
  561. * in the correct order.
  562. */
  563. public Object[] toArray() {
  564. Object[] result = new Object[size];
  565. int i = 0;
  566. for (Entry e = header.next; e != header; e = e.next)
  567. result[i++] = e.element;
  568. return result;
  569. }
  570. /**
  571. * Returns an array containing all of the elements in this list in
  572. * the correct order; the runtime type of the returned array is that of
  573. * the specified array. If the list fits in the specified array, it
  574. * is returned therein. Otherwise, a new array is allocated with the
  575. * runtime type of the specified array and the size of this list.<p>
  576. *
  577. * If the list fits in the specified array with room to spare
  578. * (i.e., the array has more elements than the list),
  579. * the element in the array immediately following the end of the
  580. * collection is set to null. This is useful in determining the length
  581. * of the list <i>only</i> if the caller knows that the list
  582. * does not contain any null elements.
  583. *
  584. * @param a the array into which the elements of the list are to
  585. * be stored, if it is big enough; otherwise, a new array of the
  586. * same runtime type is allocated for this purpose.
  587. * @return an array containing the elements of the list.
  588. * @throws ArrayStoreException if the runtime type of a is not a
  589. * supertype of the runtime type of every element in this list.
  590. * @throws NullPointerException if the specified array is null.
  591. */
  592. public Object[] toArray(Object a[]) {
  593. if (a.length < size)
  594. a = (Object[])java.lang.reflect.Array.newInstance(
  595. a.getClass().getComponentType(), size);
  596. int i = 0;
  597. for (Entry e = header.next; e != header; e = e.next)
  598. a[i++] = e.element;
  599. if (a.length > size)
  600. a[size] = null;
  601. return a;
  602. }
  603. private static final long serialVersionUID = 876323262645176354L;
  604. /**
  605. * Save the state of this <tt>LinkedList</tt> instance to a stream (that
  606. * is, serialize it).
  607. *
  608. * @serialData The size of the list (the number of elements it
  609. * contains) is emitted (int), followed by all of its
  610. * elements (each an Object) in the proper order.
  611. */
  612. private void writeObject(java.io.ObjectOutputStream s)
  613. throws java.io.IOException {
  614. // Write out any hidden serialization magic
  615. s.defaultWriteObject();
  616. // Write out size
  617. s.writeInt(size);
  618. // Write out all elements in the proper order.
  619. for (Entry e = header.next; e != header; e = e.next)
  620. s.writeObject(e.element);
  621. }
  622. /**
  623. * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is
  624. * deserialize it).
  625. */
  626. private void readObject(java.io.ObjectInputStream s)
  627. throws java.io.IOException, ClassNotFoundException {
  628. // Read in any hidden serialization magic
  629. s.defaultReadObject();
  630. // Read in size
  631. int size = s.readInt();
  632. // Initialize header
  633. header = new Entry(null, null, null);
  634. header.next = header.previous = header;
  635. // Read in all elements in the proper order.
  636. for (int i=0; i<size; i++)
  637. add(s.readObject());
  638. }
  639. }