ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.37
Committed: Mon Jul 18 01:14:34 2005 UTC (18 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.36: +15 -14 lines
Log Message:
doc fixes

File Contents

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