ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.44
Committed: Tue Feb 7 20:54:24 2006 UTC (18 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.43: +0 -1 lines
Log Message:
6378729: Remove workaround for 6280605

File Contents

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