ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.3
Committed: Sat Aug 9 19:55:14 2003 UTC (20 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.2: +293 -261 lines
Log Message:
Rebase on 1.5.0 source

File Contents

# User Rev Content
1 tim 1.1 /*
2 dl 1.3 * @(#)LinkedList.java 1.53 03/06/22
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     * the begining or the end, whichever is closer to the specified index.<p>
29     *
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.3 * @version 1.53, 06/22/03
66     * @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     if (index < 0 || index >= size)
266     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     * Retrieves, but does not remove, the head (first element) of this list..
446     * @return the head of this queue, or <tt>null</tt> if this queue is empty.
447     */
448     public E peek() {
449     if (size==0)
450     return null;
451     return getFirst();
452     }
453    
454     /**
455     * Retrieves, but does not remove, the head (first element) of this list..
456     * @return the head of this queue.
457     * @throws NoSuchElementException if this queue is empty.
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 queue, or <tt>null</tt> if this queue is empty.
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     * @return the head of this queue.
476     * @throws NoSuchElementException if this queue is empty.
477     */
478     public E remove() {
479     return removeFirst();
480     }
481    
482     /**
483     * Adds the specified element as the tail (last element) of this list.
484     *
485     * @param o the element to add.
486     * @return <tt>true</tt> (as per the general contract of
487     * <tt>Queue.offer</tt>)
488     */
489     public boolean offer(E x) {
490     return add(x);
491     }
492    
493 tim 1.1 /**
494     * Returns a list-iterator of the elements in this list (in proper
495     * sequence), starting at the specified position in the list.
496     * Obeys the general contract of <tt>List.listIterator(int)</tt>.<p>
497     *
498     * The list-iterator is <i>fail-fast</i>: if the list is structurally
499     * modified at any time after the Iterator is created, in any way except
500     * through the list-iterator's own <tt>remove</tt> or <tt>add</tt>
501     * methods, the list-iterator will throw a
502     * <tt>ConcurrentModificationException</tt>. Thus, in the face of
503     * concurrent modification, the iterator fails quickly and cleanly, rather
504     * than risking arbitrary, non-deterministic behavior at an undetermined
505     * time in the future.
506     *
507     * @param index index of first element to be returned from the
508 dl 1.3 * list-iterator (by a call to <tt>next</tt>).
509 tim 1.1 * @return a ListIterator of the elements in this list (in proper
510 dl 1.3 * sequence), starting at the specified position in the list.
511 tim 1.1 * @throws IndexOutOfBoundsException if index is out of range
512 dl 1.3 * (<tt>index &lt; 0 || index &gt; size()</tt>).
513     * @see List#listIterator(int)
514 tim 1.1 */
515 dl 1.3 public ListIterator<E> listIterator(int index) {
516     return new ListItr(index);
517 tim 1.1 }
518    
519 dl 1.3 private class ListItr implements ListIterator<E> {
520     private Entry<E> lastReturned = header;
521     private Entry<E> next;
522     private int nextIndex;
523     private int expectedModCount = modCount;
524    
525     ListItr(int index) {
526     if (index < 0 || index > size)
527     throw new IndexOutOfBoundsException("Index: "+index+
528     ", Size: "+size);
529     if (index < (size >> 1)) {
530     next = header.next;
531     for (nextIndex=0; nextIndex<index; nextIndex++)
532     next = next.next;
533     } else {
534     next = header;
535     for (nextIndex=size; nextIndex>index; nextIndex--)
536     next = next.previous;
537     }
538     }
539    
540     public boolean hasNext() {
541     return nextIndex != size;
542     }
543    
544     public E next() {
545     checkForComodification();
546     if (nextIndex == size)
547     throw new NoSuchElementException();
548    
549     lastReturned = next;
550     next = next.next;
551     nextIndex++;
552     return lastReturned.element;
553     }
554    
555     public boolean hasPrevious() {
556     return nextIndex != 0;
557     }
558    
559     public E previous() {
560     if (nextIndex == 0)
561     throw new NoSuchElementException();
562    
563     lastReturned = next = next.previous;
564     nextIndex--;
565     checkForComodification();
566     return lastReturned.element;
567     }
568    
569     public int nextIndex() {
570     return nextIndex;
571     }
572    
573     public int previousIndex() {
574     return nextIndex-1;
575     }
576 tim 1.1
577 dl 1.3 public void remove() {
578 tim 1.1 checkForComodification();
579     try {
580     LinkedList.this.remove(lastReturned);
581     } catch (NoSuchElementException e) {
582     throw new IllegalStateException();
583     }
584 dl 1.3 if (next==lastReturned)
585 tim 1.1 next = lastReturned.next;
586     else
587 dl 1.3 nextIndex--;
588     lastReturned = header;
589     expectedModCount++;
590     }
591    
592     public void set(E o) {
593     if (lastReturned == header)
594     throw new IllegalStateException();
595     checkForComodification();
596     lastReturned.element = o;
597     }
598    
599     public void add(E o) {
600     checkForComodification();
601     lastReturned = header;
602     addBefore(o, next);
603     nextIndex++;
604     expectedModCount++;
605     }
606    
607     final void checkForComodification() {
608     if (modCount != expectedModCount)
609     throw new ConcurrentModificationException();
610     }
611     }
612    
613     private static class Entry<E> {
614     E element;
615     Entry<E> next;
616     Entry<E> previous;
617    
618     Entry(E element, Entry<E> next, Entry<E> previous) {
619     this.element = element;
620     this.next = next;
621     this.previous = previous;
622     }
623     }
624    
625     private Entry<E> addBefore(E o, Entry<E> e) {
626     Entry<E> newEntry = new Entry<E>(o, e, e.previous);
627     newEntry.previous.next = newEntry;
628     newEntry.next.previous = newEntry;
629     size++;
630     modCount++;
631     return newEntry;
632     }
633    
634     private void remove(Entry<E> e) {
635     if (e == header)
636     throw new NoSuchElementException();
637    
638     e.previous.next = e.next;
639     e.next.previous = e.previous;
640     size--;
641     modCount++;
642 tim 1.1 }
643    
644     /**
645     * Returns a shallow copy of this <tt>LinkedList</tt>. (The elements
646     * themselves are not cloned.)
647     *
648     * @return a shallow copy of this <tt>LinkedList</tt> instance.
649     */
650     public Object clone() {
651 dl 1.3 LinkedList<E> clone = null;
652     try {
653     clone = (LinkedList<E>) super.clone();
654     } catch (CloneNotSupportedException e) {
655     throw new InternalError();
656     }
657 tim 1.1
658     // Put clone into "virgin" state
659 dl 1.3 clone.header = new Entry<E>(null, null, null);
660 tim 1.1 clone.header.next = clone.header.previous = clone.header;
661     clone.size = 0;
662     clone.modCount = 0;
663    
664     // Initialize clone with our elements
665 dl 1.3 for (Entry<E> e = header.next; e != header; e = e.next)
666 tim 1.1 clone.add(e.element);
667    
668     return clone;
669     }
670    
671     /**
672     * Returns an array containing all of the elements in this list
673     * in the correct order.
674     *
675     * @return an array containing all of the elements in this list
676 dl 1.3 * in the correct order.
677 tim 1.1 */
678     public Object[] toArray() {
679 dl 1.3 Object[] result = new Object[size];
680 tim 1.1 int i = 0;
681 dl 1.3 for (Entry<E> e = header.next; e != header; e = e.next)
682 tim 1.1 result[i++] = e.element;
683 dl 1.3 return result;
684 tim 1.1 }
685    
686     /**
687     * Returns an array containing all of the elements in this list in
688     * the correct order; the runtime type of the returned array is that of
689     * the specified array. If the list fits in the specified array, it
690     * is returned therein. Otherwise, a new array is allocated with the
691     * runtime type of the specified array and the size of this list.<p>
692     *
693     * If the list fits in the specified array with room to spare
694     * (i.e., the array has more elements than the list),
695     * the element in the array immediately following the end of the
696     * collection is set to null. This is useful in determining the length
697     * of the list <i>only</i> if the caller knows that the list
698     * does not contain any null elements.
699     *
700     * @param a the array into which the elements of the list are to
701 dl 1.3 * be stored, if it is big enough; otherwise, a new array of the
702     * same runtime type is allocated for this purpose.
703 tim 1.1 * @return an array containing the elements of the list.
704     * @throws ArrayStoreException if the runtime type of a is not a
705     * supertype of the runtime type of every element in this list.
706     * @throws NullPointerException if the specified array is null.
707     */
708 dl 1.3 public <T> T[] toArray(T[] a) {
709 tim 1.1 if (a.length < size)
710 dl 1.3 a = (T[])java.lang.reflect.Array.newInstance(
711 tim 1.1 a.getClass().getComponentType(), size);
712     int i = 0;
713 dl 1.3 Object[] result = a;
714     for (Entry<E> e = header.next; e != header; e = e.next)
715     result[i++] = e.element;
716 tim 1.1
717     if (a.length > size)
718     a[size] = null;
719    
720     return a;
721     }
722    
723     private static final long serialVersionUID = 876323262645176354L;
724    
725     /**
726     * Save the state of this <tt>LinkedList</tt> instance to a stream (that
727     * is, serialize it).
728     *
729     * @serialData The size of the list (the number of elements it
730 dl 1.3 * contains) is emitted (int), followed by all of its
731     * elements (each an Object) in the proper order.
732 tim 1.1 */
733 dl 1.3 private void writeObject(java.io.ObjectOutputStream s)
734 tim 1.1 throws java.io.IOException {
735 dl 1.3 // Write out any hidden serialization magic
736     s.defaultWriteObject();
737 tim 1.1
738     // Write out size
739     s.writeInt(size);
740    
741 dl 1.3 // Write out all elements in the proper order.
742 tim 1.1 for (Entry e = header.next; e != header; e = e.next)
743     s.writeObject(e.element);
744     }
745    
746     /**
747     * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is
748     * deserialize it).
749     */
750 dl 1.3 private void readObject(java.io.ObjectInputStream s)
751 tim 1.1 throws java.io.IOException, ClassNotFoundException {
752 dl 1.3 // Read in any hidden serialization magic
753     s.defaultReadObject();
754 tim 1.1
755     // Read in size
756     int size = s.readInt();
757    
758     // Initialize header
759 dl 1.3 header = new Entry<E>(null, null, null);
760 tim 1.1 header.next = header.previous = header;
761    
762 dl 1.3 // Read in all elements in the proper order.
763     for (int i=0; i<size; i++)
764     addBefore((E)s.readObject(), header);
765 tim 1.1 }
766     }