ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.8
Committed: Fri Sep 26 11:37:06 2003 UTC (20 years, 8 months ago) by dl
Branch: MAIN
Changes since 1.7: +1 -1 lines
Log Message:
Spellcheck

File Contents

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