1 /* LinkedList.java -- Linked list implementation of the List interface
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package java.util;
40 import java.io.IOException;
41 import java.io.ObjectInputStream;
42 import java.io.ObjectOutputStream;
43 import java.io.Serializable;
44 import java.lang.reflect.Array;
45 
46 /**
47  * Linked list implementation of the List interface. In addition to the
48  * methods of the List interface, this class provides access to the first
49  * and last list elements in O(1) time for easy stack, queue, or double-ended
50  * queue (deque) creation. The list is doubly-linked, with traversal to a
51  * given index starting from the end closest to the element.<p>
52  *
53  * LinkedList is not synchronized, so if you need multi-threaded access,
54  * consider using:<br>
55  * <code>List l = Collections.synchronizedList(new LinkedList(...));</code>
56  * <p>
57  *
58  * The iterators are <i>fail-fast</i>, meaning that any structural
59  * modification, except for <code>remove()</code> called on the iterator
60  * itself, cause the iterator to throw a
61  * {@link ConcurrentModificationException} rather than exhibit
62  * non-deterministic behavior.
63  *
64  * @author Original author unknown
65  * @author Bryce McKinlay
66  * @author Eric Blake (ebb9@email.byu.edu)
67  * @author Tom Tromey (tromey@redhat.com)
68  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
69  * @see List
70  * @see ArrayList
71  * @see Vector
72  * @see Collections#synchronizedList(List)
73  * @since 1.2
74  * @status Complete to 1.6
75  */
76 public class LinkedList<T> extends AbstractSequentialList<T>
77   implements List<T>, Deque<T>, Cloneable, Serializable
78 {
79   /**
80    * Compatible with JDK 1.2.
81    */
82   private static final long serialVersionUID = 876323262645176354L;
83 
84   /**
85    * The first element in the list.
86    */
87   transient Entry<T> first;
88 
89   /**
90    * The last element in the list.
91    */
92   transient Entry<T> last;
93 
94   /**
95    * The current length of the list.
96    */
97   transient int size = 0;
98 
99   /**
100    * Class to represent an entry in the list. Holds a single element.
101    */
102   private static final class Entry<T>
103   {
104     /** The element in the list. */
105     T data;
106 
107     /** The next list entry, null if this is last. */
108     Entry<T> next;
109 
110     /** The previous list entry, null if this is first. */
111     Entry<T> previous;
112 
113     /**
114      * Construct an entry.
115      * @param data the list element
116      */
Entry(T data)117     Entry(T data)
118     {
119       this.data = data;
120     }
121   } // class Entry
122 
123   /**
124    * Obtain the Entry at a given position in a list. This method of course
125    * takes linear time, but it is intelligent enough to take the shorter of the
126    * paths to get to the Entry required. This implies that the first or last
127    * entry in the list is obtained in constant time, which is a very desirable
128    * property.
129    * For speed and flexibility, range checking is not done in this method:
130    * Incorrect values will be returned if (n &lt; 0) or (n &gt;= size).
131    *
132    * @param n the number of the entry to get
133    * @return the entry at position n
134    */
135   // Package visible for use in nested classes.
getEntry(int n)136   Entry<T> getEntry(int n)
137   {
138     Entry<T> e;
139     if (n < size / 2)
140       {
141         e = first;
142         // n less than size/2, iterate from start
143         while (n-- > 0)
144           e = e.next;
145       }
146     else
147       {
148         e = last;
149         // n greater than size/2, iterate from end
150         while (++n < size)
151           e = e.previous;
152       }
153     return e;
154   }
155 
156   /**
157    * Remove an entry from the list. This will adjust size and deal with
158    *  `first' and  `last' appropriatly.
159    *
160    * @param e the entry to remove
161    */
162   // Package visible for use in nested classes.
removeEntry(Entry<T> e)163   void removeEntry(Entry<T> e)
164   {
165     modCount++;
166     size--;
167     if (size == 0)
168       first = last = null;
169     else
170       {
171         if (e == first)
172           {
173             first = e.next;
174             e.next.previous = null;
175           }
176         else if (e == last)
177           {
178             last = e.previous;
179             e.previous.next = null;
180           }
181         else
182           {
183             e.next.previous = e.previous;
184             e.previous.next = e.next;
185           }
186       }
187   }
188 
189   /**
190    * Checks that the index is in the range of possible elements (inclusive).
191    *
192    * @param index the index to check
193    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size
194    */
checkBoundsInclusive(int index)195   private void checkBoundsInclusive(int index)
196   {
197     if (index < 0 || index > size)
198       throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
199                                           + size);
200   }
201 
202   /**
203    * Checks that the index is in the range of existing elements (exclusive).
204    *
205    * @param index the index to check
206    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size
207    */
checkBoundsExclusive(int index)208   private void checkBoundsExclusive(int index)
209   {
210     if (index < 0 || index >= size)
211       throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
212                                           + size);
213   }
214 
215   /**
216    * Create an empty linked list.
217    */
LinkedList()218   public LinkedList()
219   {
220   }
221 
222   /**
223    * Create a linked list containing the elements, in order, of a given
224    * collection.
225    *
226    * @param c the collection to populate this list from
227    * @throws NullPointerException if c is null
228    */
LinkedList(Collection<? extends T> c)229   public LinkedList(Collection<? extends T> c)
230   {
231     addAll(c);
232   }
233 
234   /**
235    * Returns the first element in the list.
236    *
237    * @return the first list element
238    * @throws NoSuchElementException if the list is empty
239    */
getFirst()240   public T getFirst()
241   {
242     if (size == 0)
243       throw new NoSuchElementException();
244     return first.data;
245   }
246 
247   /**
248    * Returns the last element in the list.
249    *
250    * @return the last list element
251    * @throws NoSuchElementException if the list is empty
252    */
getLast()253   public T getLast()
254   {
255     if (size == 0)
256       throw new NoSuchElementException();
257     return last.data;
258   }
259 
260   /**
261    * Remove and return the first element in the list.
262    *
263    * @return the former first element in the list
264    * @throws NoSuchElementException if the list is empty
265    */
removeFirst()266   public T removeFirst()
267   {
268     if (size == 0)
269       throw new NoSuchElementException();
270     modCount++;
271     size--;
272     T r = first.data;
273 
274     if (first.next != null)
275       first.next.previous = null;
276     else
277       last = null;
278 
279     first = first.next;
280 
281     return r;
282   }
283 
284   /**
285    * Remove and return the last element in the list.
286    *
287    * @return the former last element in the list
288    * @throws NoSuchElementException if the list is empty
289    */
removeLast()290   public T removeLast()
291   {
292     if (size == 0)
293       throw new NoSuchElementException();
294     modCount++;
295     size--;
296     T r = last.data;
297 
298     if (last.previous != null)
299       last.previous.next = null;
300     else
301       first = null;
302 
303     last = last.previous;
304 
305     return r;
306   }
307 
308   /**
309    * Insert an element at the first of the list.
310    *
311    * @param o the element to insert
312    */
addFirst(T o)313   public void addFirst(T o)
314   {
315     Entry<T> e = new Entry(o);
316 
317     modCount++;
318     if (size == 0)
319       first = last = e;
320     else
321       {
322         e.next = first;
323         first.previous = e;
324         first = e;
325       }
326     size++;
327   }
328 
329   /**
330    * Insert an element at the last of the list.
331    *
332    * @param o the element to insert
333    */
addLast(T o)334   public void addLast(T o)
335   {
336     addLastEntry(new Entry<T>(o));
337   }
338 
339   /**
340    * Inserts an element at the end of the list.
341    *
342    * @param e the entry to add
343    */
addLastEntry(Entry<T> e)344   private void addLastEntry(Entry<T> e)
345   {
346     modCount++;
347     if (size == 0)
348       first = last = e;
349     else
350       {
351         e.previous = last;
352         last.next = e;
353         last = e;
354       }
355     size++;
356   }
357 
358   /**
359    * Returns true if the list contains the given object. Comparison is done by
360    * <code>o == null ? e = null : o.equals(e)</code>.
361    *
362    * @param o the element to look for
363    * @return true if it is found
364    */
contains(Object o)365   public boolean contains(Object o)
366   {
367     Entry<T> e = first;
368     while (e != null)
369       {
370         if (equals(o, e.data))
371           return true;
372         e = e.next;
373       }
374     return false;
375   }
376 
377   /**
378    * Returns the size of the list.
379    *
380    * @return the list size
381    */
size()382   public int size()
383   {
384     return size;
385   }
386 
387   /**
388    * Adds an element to the end of the list.
389    *
390    * @param o the entry to add
391    * @return true, as it always succeeds
392    */
add(T o)393   public boolean add(T o)
394   {
395     addLastEntry(new Entry<T>(o));
396     return true;
397   }
398 
399   /**
400    * Removes the entry at the lowest index in the list that matches the given
401    * object, comparing by <code>o == null ? e = null : o.equals(e)</code>.
402    *
403    * @param o the object to remove
404    * @return true if an instance of the object was removed
405    */
remove(Object o)406   public boolean remove(Object o)
407   {
408     Entry<T> e = first;
409     while (e != null)
410       {
411         if (equals(o, e.data))
412           {
413             removeEntry(e);
414             return true;
415           }
416         e = e.next;
417       }
418     return false;
419   }
420 
421   /**
422    * Append the elements of the collection in iteration order to the end of
423    * this list. If this list is modified externally (for example, if this
424    * list is the collection), behavior is unspecified.
425    *
426    * @param c the collection to append
427    * @return true if the list was modified
428    * @throws NullPointerException if c is null
429    */
addAll(Collection<? extends T> c)430   public boolean addAll(Collection<? extends T> c)
431   {
432     return addAll(size, c);
433   }
434 
435   /**
436    * Insert the elements of the collection in iteration order at the given
437    * index of this list. If this list is modified externally (for example,
438    * if this list is the collection), behavior is unspecified.
439    *
440    * @param c the collection to append
441    * @return true if the list was modified
442    * @throws NullPointerException if c is null
443    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
444    */
addAll(int index, Collection<? extends T> c)445   public boolean addAll(int index, Collection<? extends T> c)
446   {
447     checkBoundsInclusive(index);
448     int csize = c.size();
449 
450     if (csize == 0)
451       return false;
452 
453     Iterator<? extends T> itr = c.iterator();
454 
455     // Get the entries just before and after index. If index is at the start
456     // of the list, BEFORE is null. If index is at the end of the list, AFTER
457     // is null. If the list is empty, both are null.
458     Entry<T> after = null;
459     Entry<T> before = null;
460     if (index != size)
461       {
462         after = getEntry(index);
463         before = after.previous;
464       }
465     else
466       before = last;
467 
468     // Create the first new entry. We do not yet set the link from `before'
469     // to the first entry, in order to deal with the case where (c == this).
470     // [Actually, we don't have to handle this case to fufill the
471     // contract for addAll(), but Sun's implementation appears to.]
472     Entry<T> e = new Entry<T>(itr.next());
473     e.previous = before;
474     Entry<T> prev = e;
475     Entry<T> firstNew = e;
476 
477     // Create and link all the remaining entries.
478     for (int pos = 1; pos < csize; pos++)
479       {
480         e = new Entry<T>(itr.next());
481         e.previous = prev;
482         prev.next = e;
483         prev = e;
484       }
485 
486     // Link the new chain of entries into the list.
487     modCount++;
488     size += csize;
489     prev.next = after;
490     if (after != null)
491       after.previous = e;
492     else
493       last = e;
494 
495     if (before != null)
496       before.next = firstNew;
497     else
498       first = firstNew;
499     return true;
500   }
501 
502   /**
503    * Remove all elements from this list.
504    */
clear()505   public void clear()
506   {
507     if (size > 0)
508       {
509         modCount++;
510         first = null;
511         last = null;
512         size = 0;
513       }
514   }
515 
516   /**
517    * Return the element at index.
518    *
519    * @param index the place to look
520    * @return the element at index
521    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
522    */
get(int index)523   public T get(int index)
524   {
525     checkBoundsExclusive(index);
526     return getEntry(index).data;
527   }
528 
529   /**
530    * Replace the element at the given location in the list.
531    *
532    * @param index which index to change
533    * @param o the new element
534    * @return the prior element
535    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
536    */
set(int index, T o)537   public T set(int index, T o)
538   {
539     checkBoundsExclusive(index);
540     Entry<T> e = getEntry(index);
541     T old = e.data;
542     e.data = o;
543     return old;
544   }
545 
546   /**
547    * Inserts an element in the given position in the list.
548    *
549    * @param index where to insert the element
550    * @param o the element to insert
551    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
552    */
add(int index, T o)553   public void add(int index, T o)
554   {
555     checkBoundsInclusive(index);
556     Entry<T> e = new Entry<T>(o);
557 
558     if (index < size)
559       {
560         modCount++;
561         Entry<T> after = getEntry(index);
562         e.next = after;
563         e.previous = after.previous;
564         if (after.previous == null)
565           first = e;
566         else
567           after.previous.next = e;
568         after.previous = e;
569         size++;
570       }
571     else
572       addLastEntry(e);
573   }
574 
575   /**
576    * Removes the element at the given position from the list.
577    *
578    * @param index the location of the element to remove
579    * @return the removed element
580    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
581    */
remove(int index)582   public T remove(int index)
583   {
584     checkBoundsExclusive(index);
585     Entry<T> e = getEntry(index);
586     removeEntry(e);
587     return e.data;
588   }
589 
590   /**
591    * Returns the first index where the element is located in the list, or -1.
592    *
593    * @param o the element to look for
594    * @return its position, or -1 if not found
595    */
indexOf(Object o)596   public int indexOf(Object o)
597   {
598     int index = 0;
599     Entry<T> e = first;
600     while (e != null)
601       {
602         if (equals(o, e.data))
603           return index;
604         index++;
605         e = e.next;
606       }
607     return -1;
608   }
609 
610   /**
611    * Returns the last index where the element is located in the list, or -1.
612    *
613    * @param o the element to look for
614    * @return its position, or -1 if not found
615    */
lastIndexOf(Object o)616   public int lastIndexOf(Object o)
617   {
618     int index = size - 1;
619     Entry<T> e = last;
620     while (e != null)
621       {
622         if (equals(o, e.data))
623           return index;
624         index--;
625         e = e.previous;
626       }
627     return -1;
628   }
629 
630   /**
631    * Obtain a ListIterator over this list, starting at a given index. The
632    * ListIterator returned by this method supports the add, remove and set
633    * methods.
634    *
635    * @param index the index of the element to be returned by the first call to
636    *        next(), or size() to be initially positioned at the end of the list
637    * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
638    */
listIterator(int index)639   public ListIterator<T> listIterator(int index)
640   {
641     checkBoundsInclusive(index);
642     return new LinkedListItr<T>(index);
643   }
644 
645   /**
646    * Create a shallow copy of this LinkedList (the elements are not cloned).
647    *
648    * @return an object of the same class as this object, containing the
649    *         same elements in the same order
650    */
clone()651   public Object clone()
652   {
653     LinkedList<T> copy = null;
654     try
655       {
656         copy = (LinkedList<T>) super.clone();
657       }
658     catch (CloneNotSupportedException ex)
659       {
660       }
661     copy.clear();
662     copy.addAll(this);
663     return copy;
664   }
665 
666   /**
667    * Returns an array which contains the elements of the list in order.
668    *
669    * @return an array containing the list elements
670    */
toArray()671   public Object[] toArray()
672   {
673     Object[] array = new Object[size];
674     Entry<T> e = first;
675     for (int i = 0; i < size; i++)
676       {
677         array[i] = e.data;
678         e = e.next;
679       }
680     return array;
681   }
682 
683   /**
684    * Returns an Array whose component type is the runtime component type of
685    * the passed-in Array.  The returned Array is populated with all of the
686    * elements in this LinkedList.  If the passed-in Array is not large enough
687    * to store all of the elements in this List, a new Array will be created
688    * and returned; if the passed-in Array is <i>larger</i> than the size
689    * of this List, then size() index will be set to null.
690    *
691    * @param a the passed-in Array
692    * @return an array representation of this list
693    * @throws ArrayStoreException if the runtime type of a does not allow
694    *         an element in this list
695    * @throws NullPointerException if a is null
696    */
toArray(S[] a)697   public <S> S[] toArray(S[] a)
698   {
699     if (a.length < size)
700       a = (S[]) Array.newInstance(a.getClass().getComponentType(), size);
701     else if (a.length > size)
702       a[size] = null;
703     Entry<T> e = first;
704     for (int i = 0; i < size; i++)
705       {
706         a[i] = (S) e.data;
707         e = e.next;
708       }
709     return a;
710   }
711 
712   /**
713    * Adds the specified element to the end of the list.
714    *
715    * @param value the value to add.
716    * @return true.
717    * @since 1.5
718    */
offer(T value)719   public boolean offer(T value)
720   {
721     return add(value);
722   }
723 
724   /**
725    * Returns the first element of the list without removing
726    * it.
727    *
728    * @return the first element of the list.
729    * @throws NoSuchElementException if the list is empty.
730    * @since 1.5
731    */
element()732   public T element()
733   {
734     return getFirst();
735   }
736 
737   /**
738    * Returns the first element of the list without removing
739    * it.
740    *
741    * @return the first element of the list, or <code>null</code>
742    *         if the list is empty.
743    * @since 1.5
744    */
peek()745   public T peek()
746   {
747     if (size == 0)
748       return null;
749     return getFirst();
750   }
751 
752   /**
753    * Removes and returns the first element of the list.
754    *
755    * @return the first element of the list, or <code>null</code>
756    *         if the list is empty.
757    * @since 1.5
758    */
poll()759   public T poll()
760   {
761     if (size == 0)
762       return null;
763     return removeFirst();
764   }
765 
766   /**
767    * Removes and returns the first element of the list.
768    *
769    * @return the first element of the list.
770    * @throws NoSuchElementException if the list is empty.
771    * @since 1.5
772    */
remove()773   public T remove()
774   {
775     return removeFirst();
776   }
777 
778   /**
779    * Serializes this object to the given stream.
780    *
781    * @param s the stream to write to
782    * @throws IOException if the underlying stream fails
783    * @serialData the size of the list (int), followed by all the elements
784    *             (Object) in proper order
785    */
writeObject(ObjectOutputStream s)786   private void writeObject(ObjectOutputStream s) throws IOException
787   {
788     s.defaultWriteObject();
789     s.writeInt(size);
790     Entry<T> e = first;
791     while (e != null)
792       {
793         s.writeObject(e.data);
794         e = e.next;
795       }
796   }
797 
798   /**
799    * Deserializes this object from the given stream.
800    *
801    * @param s the stream to read from
802    * @throws ClassNotFoundException if the underlying stream fails
803    * @throws IOException if the underlying stream fails
804    * @serialData the size of the list (int), followed by all the elements
805    *             (Object) in proper order
806    */
readObject(ObjectInputStream s)807   private void readObject(ObjectInputStream s)
808     throws IOException, ClassNotFoundException
809   {
810     s.defaultReadObject();
811     int i = s.readInt();
812     while (--i >= 0)
813       addLastEntry(new Entry<T>((T) s.readObject()));
814   }
815 
816   /**
817    * A ListIterator over the list. This class keeps track of its
818    * position in the list and the two list entries it is between.
819    *
820    * @author Original author unknown
821    * @author Eric Blake (ebb9@email.byu.edu)
822    */
823   private final class LinkedListItr<I>
824     implements ListIterator<I>
825   {
826     /** Number of modifications we know about. */
827     private int knownMod = modCount;
828 
829     /** Entry that will be returned by next(). */
830     private Entry<I> next;
831 
832     /** Entry that will be returned by previous(). */
833     private Entry<I> previous;
834 
835     /** Entry that will be affected by remove() or set(). */
836     private Entry<I> lastReturned;
837 
838     /** Index of `next'. */
839     private int position;
840 
841     /**
842      * Initialize the iterator.
843      *
844      * @param index the initial index
845      */
LinkedListItr(int index)846     LinkedListItr(int index)
847     {
848       if (index == size)
849         {
850           next = null;
851           previous = (Entry<I>) last;
852         }
853       else
854         {
855           next = (Entry<I>) getEntry(index);
856           previous = next.previous;
857         }
858       position = index;
859     }
860 
861     /**
862      * Checks for iterator consistency.
863      *
864      * @throws ConcurrentModificationException if the list was modified
865      */
checkMod()866     private void checkMod()
867     {
868       if (knownMod != modCount)
869         throw new ConcurrentModificationException();
870     }
871 
872     /**
873      * Returns the index of the next element.
874      *
875      * @return the next index
876      */
nextIndex()877     public int nextIndex()
878     {
879       return position;
880     }
881 
882     /**
883      * Returns the index of the previous element.
884      *
885      * @return the previous index
886      */
previousIndex()887     public int previousIndex()
888     {
889       return position - 1;
890     }
891 
892     /**
893      * Returns true if more elements exist via next.
894      *
895      * @return true if next will succeed
896      */
hasNext()897     public boolean hasNext()
898     {
899       return (next != null);
900     }
901 
902     /**
903      * Returns true if more elements exist via previous.
904      *
905      * @return true if previous will succeed
906      */
hasPrevious()907     public boolean hasPrevious()
908     {
909       return (previous != null);
910     }
911 
912     /**
913      * Returns the next element.
914      *
915      * @return the next element
916      * @throws ConcurrentModificationException if the list was modified
917      * @throws NoSuchElementException if there is no next
918      */
next()919     public I next()
920     {
921       checkMod();
922       if (next == null)
923         throw new NoSuchElementException();
924       position++;
925       lastReturned = previous = next;
926       next = lastReturned.next;
927       return lastReturned.data;
928     }
929 
930     /**
931      * Returns the previous element.
932      *
933      * @return the previous element
934      * @throws ConcurrentModificationException if the list was modified
935      * @throws NoSuchElementException if there is no previous
936      */
previous()937     public I previous()
938     {
939       checkMod();
940       if (previous == null)
941         throw new NoSuchElementException();
942       position--;
943       lastReturned = next = previous;
944       previous = lastReturned.previous;
945       return lastReturned.data;
946     }
947 
948     /**
949      * Remove the most recently returned element from the list.
950      *
951      * @throws ConcurrentModificationException if the list was modified
952      * @throws IllegalStateException if there was no last element
953      */
remove()954     public void remove()
955     {
956       checkMod();
957       if (lastReturned == null)
958         throw new IllegalStateException();
959 
960       // Adjust the position to before the removed element, if the element
961       // being removed is behind the cursor.
962       if (lastReturned == previous)
963         position--;
964 
965       next = lastReturned.next;
966       previous = lastReturned.previous;
967       removeEntry((Entry<T>) lastReturned);
968       knownMod++;
969 
970       lastReturned = null;
971     }
972 
973     /**
974      * Adds an element between the previous and next, and advance to the next.
975      *
976      * @param o the element to add
977      * @throws ConcurrentModificationException if the list was modified
978      */
add(I o)979     public void add(I o)
980     {
981       checkMod();
982       modCount++;
983       knownMod++;
984       size++;
985       position++;
986       Entry<I> e = new Entry<I>(o);
987       e.previous = previous;
988       e.next = next;
989 
990       if (previous != null)
991         previous.next = e;
992       else
993         first = (Entry<T>) e;
994 
995       if (next != null)
996         next.previous = e;
997       else
998         last = (Entry<T>) e;
999 
1000       previous = e;
1001       lastReturned = null;
1002     }
1003 
1004     /**
1005      * Changes the contents of the element most recently returned.
1006      *
1007      * @param o the new element
1008      * @throws ConcurrentModificationException if the list was modified
1009      * @throws IllegalStateException if there was no last element
1010      */
set(I o)1011     public void set(I o)
1012     {
1013       checkMod();
1014       if (lastReturned == null)
1015         throw new IllegalStateException();
1016       lastReturned.data = o;
1017     }
1018   } // class LinkedListItr
1019 
1020   /**
1021    * Obtain an Iterator over this list in reverse sequential order.
1022    *
1023    * @return an Iterator over the elements of the list in
1024    *         reverse order.
1025    * @since 1.6
1026    */
descendingIterator()1027   public Iterator<T> descendingIterator()
1028   {
1029     return new Iterator<T>()
1030     {
1031       /** Number of modifications we know about. */
1032       private int knownMod = modCount;
1033 
1034       /** Entry that will be returned by next(). */
1035       private Entry<T> next = last;
1036 
1037       /** Entry that will be affected by remove() or set(). */
1038       private Entry<T> lastReturned;
1039 
1040       /** Index of `next'. */
1041       private int position = size() - 1;
1042 
1043       // This will get inlined, since it is private.
1044       /**
1045        * Checks for modifications made to the list from
1046        * elsewhere while iteration is in progress.
1047        *
1048        * @throws ConcurrentModificationException if the
1049        *         list has been modified elsewhere.
1050        */
1051       private void checkMod()
1052       {
1053         if (knownMod != modCount)
1054           throw new ConcurrentModificationException();
1055       }
1056 
1057       /**
1058        * Tests to see if there are any more objects to
1059        * return.
1060        *
1061        * @return true if the start of the list has not yet been
1062        *         reached.
1063        */
1064       public boolean hasNext()
1065       {
1066         return next != null;
1067       }
1068 
1069       /**
1070        * Retrieves the next object from the list.
1071        *
1072        * @return The next object.
1073        * @throws NoSuchElementException if there are
1074        *         no more objects to retrieve.
1075        * @throws ConcurrentModificationException if the
1076        *         list has been modified elsewhere.
1077        */
1078       public T next()
1079       {
1080         checkMod();
1081         if (next == null)
1082           throw new NoSuchElementException();
1083         --position;
1084         lastReturned = next;
1085         next = lastReturned.previous;
1086         return lastReturned.data;
1087       }
1088 
1089       /**
1090        * Removes the last object retrieved by <code>next()</code>
1091        * from the list, if the list supports object removal.
1092        *
1093        * @throws ConcurrentModificationException if the list
1094        *         has been modified elsewhere.
1095        * @throws IllegalStateException if the iterator is positioned
1096        *         before the start of the list or the last object has already
1097        *         been removed.
1098        */
1099       public void remove()
1100       {
1101         checkMod();
1102         if (lastReturned == null)
1103           throw new IllegalStateException();
1104         removeEntry(lastReturned);
1105         lastReturned = null;
1106         ++knownMod;
1107       }
1108     };
1109   }
1110 
1111   /**
1112    * Inserts the specified element at the front of the list.
1113    *
1114    * @param value the element to insert.
1115    * @return true.
1116    * @since 1.6
1117    */
offerFirst(T value)1118   public boolean offerFirst(T value)
1119   {
1120     addFirst(value);
1121     return true;
1122   }
1123 
1124   /**
1125    * Inserts the specified element at the end of the list.
1126    *
1127    * @param value the element to insert.
1128    * @return true.
1129    * @since 1.6
1130    */
offerLast(T value)1131   public boolean offerLast(T value)
1132   {
1133     return add(value);
1134   }
1135 
1136   /**
1137    * Returns the first element of the list without removing
1138    * it.
1139    *
1140    * @return the first element of the list, or <code>null</code>
1141    *         if the list is empty.
1142    * @since 1.6
1143    */
peekFirst()1144   public T peekFirst()
1145   {
1146     return peek();
1147   }
1148 
1149   /**
1150    * Returns the last element of the list without removing
1151    * it.
1152    *
1153    * @return the last element of the list, or <code>null</code>
1154    *         if the list is empty.
1155    * @since 1.6
1156    */
peekLast()1157   public T peekLast()
1158   {
1159     if (size == 0)
1160       return null;
1161     return getLast();
1162   }
1163 
1164   /**
1165    * Removes and returns the first element of the list.
1166    *
1167    * @return the first element of the list, or <code>null</code>
1168    *         if the list is empty.
1169    * @since 1.6
1170    */
pollFirst()1171   public T pollFirst()
1172   {
1173     return poll();
1174   }
1175 
1176   /**
1177    * Removes and returns the last element of the list.
1178    *
1179    * @return the last element of the list, or <code>null</code>
1180    *         if the list is empty.
1181    * @since 1.6
1182    */
pollLast()1183   public T pollLast()
1184   {
1185     if (size == 0)
1186       return null;
1187     return removeLast();
1188   }
1189 
1190   /**
1191    * Pops an element from the stack by removing and returning
1192    * the first element in the list.  This is equivalent to
1193    * calling {@link #removeFirst()}.
1194    *
1195    * @return the top of the stack, which is the first element
1196    *         of the list.
1197    * @throws NoSuchElementException if the list is empty.
1198    * @since 1.6
1199    * @see #removeFirst()
1200    */
pop()1201   public T pop()
1202   {
1203     return removeFirst();
1204   }
1205 
1206   /**
1207    * Pushes an element on to the stack by adding it to the
1208    * front of the list.  This is equivalent to calling
1209    * {@link #addFirst(T)}.
1210    *
1211    * @param value the element to push on to the stack.
1212    * @throws NoSuchElementException if the list is empty.
1213    * @since 1.6
1214    * @see #addFirst(T)
1215    */
push(T value)1216   public void push(T value)
1217   {
1218     addFirst(value);
1219   }
1220 
1221   /**
1222    * Removes the first occurrence of the specified element
1223    * from the list, when traversing the list from head to
1224    * tail.  The list is unchanged if the element is not found.
1225    * This is equivalent to calling {@link #remove(Object)}.
1226    *
1227    * @param o the element to remove.
1228    * @return true if an instance of the object was removed.
1229    * @since 1.6
1230    */
removeFirstOccurrence(Object o)1231   public boolean removeFirstOccurrence(Object o)
1232   {
1233     return remove(o);
1234   }
1235 
1236   /**
1237    * Removes the last occurrence of the specified element
1238    * from the list, when traversing the list from head to
1239    * tail.  The list is unchanged if the element is not found.
1240    *
1241    * @param o the element to remove.
1242    * @return true if an instance of the object was removed.
1243    * @since 1.6
1244    */
removeLastOccurrence(Object o)1245   public boolean removeLastOccurrence(Object o)
1246   {
1247     Entry<T> e = last;
1248     while (e != null)
1249       {
1250         if (equals(o, e.data))
1251           {
1252             removeEntry(e);
1253             return true;
1254           }
1255         e = e.previous;
1256       }
1257     return false;
1258   }
1259 
1260 }
1261