ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/LinkedList.java
Revision: 1.49
Committed: Sun May 18 23:59:57 2008 UTC (16 years ago) by jsr166
Branch: MAIN
Changes since 1.48: +0 -1 lines
Log Message:
Sync with OpenJDK; remove all @version tags

File Contents

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