ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.36
Committed: Sat Jun 18 01:56:01 2005 UTC (18 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.35: +9 -5 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
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 * <b>Note that this implementation is not synchronized.</b> If multiple
30 * threads access a list concurrently, and at least one of the threads
31 * modifies the list structurally, it <i>must</i> be synchronized
32 * externally. (A structural modification is any operation that adds or
33 * deletes one or more elements; merely setting the value of an element is not
34 * a structural modification.) This is typically accomplished by
35 * synchronizing on some object that naturally encapsulates the list. If no
36 * such object exists, the list should be "wrapped" using the
37 * Collections.synchronizedList method. This is best done at creation time,
38 * to prevent accidental unsynchronized access to the list: <pre>
39 * List list = Collections.synchronizedList(new LinkedList(...));
40 * </pre>
41 *
42 * <p>The iterators returned by this class's <tt>iterator</tt> and
43 * <tt>listIterator</tt> methods are <i>fail-fast</i>: if the list is
44 * structurally modified at any time after the iterator is created, in
45 * any way except through the Iterator's own <tt>remove</tt> or
46 * <tt>add</tt> methods, the iterator will throw a {@link
47 * ConcurrentModificationException}. Thus, in the face of concurrent
48 * modification, the iterator fails quickly and cleanly, rather than
49 * risking arbitrary, non-deterministic behavior at an undetermined
50 * time in the future.
51 *
52 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
53 * as it is, generally speaking, impossible to make any hard guarantees in the
54 * presence of unsynchronized concurrent modification. Fail-fast iterators
55 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
56 * Therefore, it would be wrong to write a program that depended on this
57 * exception for its correctness: <i>the fail-fast behavior of iterators
58 * should be used only to detect bugs.</i>
59 *
60 * <p>This class is a member of the
61 * <a href="{@docRoot}/../guide/collections/index.html">
62 * Java Collections Framework</a>.
63 *
64 * @author Josh Bloch
65 * @version %I%, %G%
66 * @see List
67 * @see ArrayList
68 * @see Vector
69 * @see Collections#synchronizedList(List)
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 per the spec for {@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 per the spec for {@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 per the spec for {@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 per the spec for {@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, or
550 * <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, or
564 * <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 * Returns a shallow copy of this <tt>LinkedList</tt>. (The elements
802 * themselves are not cloned.)
803 *
804 * @return a shallow copy of this <tt>LinkedList</tt> instance
805 */
806 public Object clone() {
807 LinkedList<E> clone = null;
808 try {
809 clone = (LinkedList<E>) super.clone();
810 } catch (CloneNotSupportedException e) {
811 throw new InternalError();
812 }
813
814 // Put clone into "virgin" state
815 clone.header = new Entry<E>(null, null, null);
816 clone.header.next = clone.header.previous = clone.header;
817 clone.size = 0;
818 clone.modCount = 0;
819
820 // Initialize clone with our elements
821 for (Entry<E> e = header.next; e != header; e = e.next)
822 clone.add(e.element);
823
824 return clone;
825 }
826
827 /**
828 * Returns an array containing all of the elements in this list
829 * in proper sequence (from first to last element).
830 *
831 * <p>The returned array will be "safe" in that no references to it are
832 * maintained by this list. (In other words, this method must allocate
833 * a new array). The caller is thus free to modify the returned array.
834 *
835 * <p>This method acts as bridge between array-based and collection-based
836 * APIs.
837 *
838 * @return an array containing all of the elements in this list
839 * in proper sequence
840 */
841 public Object[] toArray() {
842 Object[] result = new Object[size];
843 int i = 0;
844 for (Entry<E> e = header.next; e != header; e = e.next)
845 result[i++] = e.element;
846 return result;
847 }
848
849 /**
850 * Returns an array containing all of the elements in this list in
851 * proper sequence (from first to last element); the runtime type of
852 * the returned array is that of the specified array. If the list fits
853 * in the specified array, it is returned therein. Otherwise, a new
854 * array is allocated with the runtime type of the specified array and
855 * the size of this list.
856 *
857 * <p>If the list fits in the specified array with room to spare (i.e.,
858 * the array has more elements than the list), the element in the array
859 * immediately following the end of the list is set to <tt>null</tt>.
860 * (This is useful in determining the length of the list <i>only</i> if
861 * the caller knows that the list does not contain any null elements.)
862 *
863 * <p>Like the {@link #toArray()} method, this method acts as bridge between
864 * array-based and collection-based APIs. Further, this method allows
865 * precise control over the runtime type of the output array, and may,
866 * under certain circumstances, be used to save allocation costs.
867 *
868 * <p>Suppose <tt>x</tt> is a list known to contain only strings.
869 * The following code can be used to dump the list into a newly
870 * allocated array of <tt>String</tt>:
871 *
872 * <pre>
873 * String[] y = x.toArray(new String[0]);</pre>
874 *
875 * Note that <tt>toArray(new Object[0])</tt> is identical in function to
876 * <tt>toArray()</tt>.
877 *
878 * @param a the array into which the elements of the list are to
879 * be stored, if it is big enough; otherwise, a new array of the
880 * same runtime type is allocated for this purpose.
881 * @return an array containing the elements of the list
882 * @throws ArrayStoreException if the runtime type of the specified array
883 * is not a supertype of the runtime type of every element in
884 * this list
885 * @throws NullPointerException if the specified array is null
886 */
887 public <T> T[] toArray(T[] a) {
888 if (a.length < size)
889 a = (T[])java.lang.reflect.Array.newInstance(
890 a.getClass().getComponentType(), size);
891 int i = 0;
892 Object[] result = a;
893 for (Entry<E> e = header.next; e != header; e = e.next)
894 result[i++] = e.element;
895
896 if (a.length > size)
897 a[size] = null;
898
899 return a;
900 }
901
902 private static final long serialVersionUID = 876323262645176354L;
903
904 /**
905 * Save the state of this <tt>LinkedList</tt> instance to a stream (that
906 * is, serialize it).
907 *
908 * @serialData The size of the list (the number of elements it
909 * contains) is emitted (int), followed by all of its
910 * elements (each an Object) in the proper order.
911 */
912 private void writeObject(java.io.ObjectOutputStream s)
913 throws java.io.IOException {
914 // Write out any hidden serialization magic
915 s.defaultWriteObject();
916
917 // Write out size
918 s.writeInt(size);
919
920 // Write out all elements in the proper order.
921 for (Entry e = header.next; e != header; e = e.next)
922 s.writeObject(e.element);
923 }
924
925 /**
926 * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is
927 * deserialize it).
928 */
929 private void readObject(java.io.ObjectInputStream s)
930 throws java.io.IOException, ClassNotFoundException {
931 // Read in any hidden serialization magic
932 s.defaultReadObject();
933
934 // Read in size
935 int size = s.readInt();
936
937 // Initialize header
938 header = new Entry<E>(null, null, null);
939 header.next = header.previous = header;
940
941 // Read in all elements in the proper order.
942 for (int i=0; i<size; i++)
943 addBefore((E)s.readObject(), header);
944 }
945 }