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.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
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
;
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>
53 * LinkedList is not synchronized, so if you need multi-threaded access,
55 * <code>List l = Collections.synchronizedList(new LinkedList(...));</code>
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.
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)
72 * @see Collections#synchronizedList(List)
74 * @status Complete to 1.6
76 public class LinkedList
<T
> extends AbstractSequentialList
<T
>
77 implements List
<T
>, Deque
<T
>, Cloneable
, Serializable
80 * Compatible with JDK 1.2.
82 private static final long serialVersionUID
= 876323262645176354L;
85 * The first element in the list.
87 transient Entry
<T
> first
;
90 * The last element in the list.
92 transient Entry
<T
> last
;
95 * The current length of the list.
97 transient int size
= 0;
100 * Class to represent an entry in the list. Holds a single element.
102 private static final class Entry
<T
>
104 /** The element in the list. */
107 /** The next list entry, null if this is last. */
110 /** The previous list entry, null if this is first. */
114 * Construct an entry.
115 * @param data the list element
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
129 * For speed and flexibility, range checking is not done in this method:
130 * Incorrect values will be returned if (n < 0) or (n >= size).
132 * @param n the number of the entry to get
133 * @return the entry at position n
135 // Package visible for use in nested classes.
136 Entry
<T
> getEntry(int n
)
142 // n less than size/2, iterate from start
149 // n greater than size/2, iterate from end
157 * Remove an entry from the list. This will adjust size and deal with
158 * `first' and `last' appropriatly.
160 * @param e the entry to remove
162 // Package visible for use in nested classes.
163 void removeEntry(Entry
<T
> e
)
174 e
.next
.previous
= null;
179 e
.previous
.next
= null;
183 e
.next
.previous
= e
.previous
;
184 e
.previous
.next
= e
.next
;
190 * Checks that the index is in the range of possible elements (inclusive).
192 * @param index the index to check
193 * @throws IndexOutOfBoundsException if index < 0 || index > size
195 private void checkBoundsInclusive(int index
)
197 if (index
< 0 || index
> size
)
198 throw new IndexOutOfBoundsException("Index: " + index
+ ", Size:"
203 * Checks that the index is in the range of existing elements (exclusive).
205 * @param index the index to check
206 * @throws IndexOutOfBoundsException if index < 0 || index >= size
208 private void checkBoundsExclusive(int index
)
210 if (index
< 0 || index
>= size
)
211 throw new IndexOutOfBoundsException("Index: " + index
+ ", Size:"
216 * Create an empty linked list.
223 * Create a linked list containing the elements, in order, of a given
226 * @param c the collection to populate this list from
227 * @throws NullPointerException if c is null
229 public LinkedList(Collection
<?
extends T
> c
)
235 * Returns the first element in the list.
237 * @return the first list element
238 * @throws NoSuchElementException if the list is empty
243 throw new NoSuchElementException();
248 * Returns the last element in the list.
250 * @return the last list element
251 * @throws NoSuchElementException if the list is empty
256 throw new NoSuchElementException();
261 * Remove and return the first element in the list.
263 * @return the former first element in the list
264 * @throws NoSuchElementException if the list is empty
266 public T
removeFirst()
269 throw new NoSuchElementException();
274 if (first
.next
!= null)
275 first
.next
.previous
= null;
285 * Remove and return the last element in the list.
287 * @return the former last element in the list
288 * @throws NoSuchElementException if the list is empty
290 public T
removeLast()
293 throw new NoSuchElementException();
298 if (last
.previous
!= null)
299 last
.previous
.next
= null;
303 last
= last
.previous
;
309 * Insert an element at the first of the list.
311 * @param o the element to insert
313 public void addFirst(T o
)
315 Entry
<T
> e
= new Entry(o
);
330 * Insert an element at the last of the list.
332 * @param o the element to insert
334 public void addLast(T o
)
336 addLastEntry(new Entry
<T
>(o
));
340 * Inserts an element at the end of the list.
342 * @param e the entry to add
344 private void addLastEntry(Entry
<T
> e
)
359 * Returns true if the list contains the given object. Comparison is done by
360 * <code>o == null ? e = null : o.equals(e)</code>.
362 * @param o the element to look for
363 * @return true if it is found
365 public boolean contains(Object o
)
370 if (equals(o
, e
.data
))
378 * Returns the size of the list.
380 * @return the list size
388 * Adds an element to the end of the list.
390 * @param o the entry to add
391 * @return true, as it always succeeds
393 public boolean add(T o
)
395 addLastEntry(new Entry
<T
>(o
));
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>.
403 * @param o the object to remove
404 * @return true if an instance of the object was removed
406 public boolean remove(Object o
)
411 if (equals(o
, e
.data
))
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.
426 * @param c the collection to append
427 * @return true if the list was modified
428 * @throws NullPointerException if c is null
430 public boolean addAll(Collection
<?
extends T
> c
)
432 return addAll(size
, c
);
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.
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 < 0 || index > size()
445 public boolean addAll(int index
, Collection
<?
extends T
> c
)
447 checkBoundsInclusive(index
);
448 int csize
= c
.size();
453 Iterator
<?
extends T
> itr
= c
.iterator();
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;
462 after
= getEntry(index
);
463 before
= after
.previous
;
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());
475 Entry
<T
> firstNew
= e
;
477 // Create and link all the remaining entries.
478 for (int pos
= 1; pos
< csize
; pos
++)
480 e
= new Entry
<T
>(itr
.next());
486 // Link the new chain of entries into the list.
496 before
.next
= firstNew
;
503 * Remove all elements from this list.
517 * Return the element at index.
519 * @param index the place to look
520 * @return the element at index
521 * @throws IndexOutOfBoundsException if index < 0 || index >= size()
523 public T
get(int index
)
525 checkBoundsExclusive(index
);
526 return getEntry(index
).data
;
530 * Replace the element at the given location in the list.
532 * @param index which index to change
533 * @param o the new element
534 * @return the prior element
535 * @throws IndexOutOfBoundsException if index < 0 || index >= size()
537 public T
set(int index
, T o
)
539 checkBoundsExclusive(index
);
540 Entry
<T
> e
= getEntry(index
);
547 * Inserts an element in the given position in the list.
549 * @param index where to insert the element
550 * @param o the element to insert
551 * @throws IndexOutOfBoundsException if index < 0 || index > size()
553 public void add(int index
, T o
)
555 checkBoundsInclusive(index
);
556 Entry
<T
> e
= new Entry
<T
>(o
);
561 Entry
<T
> after
= getEntry(index
);
563 e
.previous
= after
.previous
;
564 if (after
.previous
== null)
567 after
.previous
.next
= e
;
576 * Removes the element at the given position from the list.
578 * @param index the location of the element to remove
579 * @return the removed element
580 * @throws IndexOutOfBoundsException if index < 0 || index > size()
582 public T
remove(int index
)
584 checkBoundsExclusive(index
);
585 Entry
<T
> e
= getEntry(index
);
591 * Returns the first index where the element is located in the list, or -1.
593 * @param o the element to look for
594 * @return its position, or -1 if not found
596 public int indexOf(Object o
)
602 if (equals(o
, e
.data
))
611 * Returns the last index where the element is located in the list, or -1.
613 * @param o the element to look for
614 * @return its position, or -1 if not found
616 public int lastIndexOf(Object o
)
618 int index
= size
- 1;
622 if (equals(o
, e
.data
))
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
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 < 0 || index > size()
639 public ListIterator
<T
> listIterator(int index
)
641 checkBoundsInclusive(index
);
642 return new LinkedListItr
<T
>(index
);
646 * Create a shallow copy of this LinkedList (the elements are not cloned).
648 * @return an object of the same class as this object, containing the
649 * same elements in the same order
651 public Object
clone()
653 LinkedList
<T
> copy
= null;
656 copy
= (LinkedList
<T
>) super.clone();
658 catch (CloneNotSupportedException ex
)
667 * Returns an array which contains the elements of the list in order.
669 * @return an array containing the list elements
671 public Object
[] toArray()
673 Object
[] array
= new Object
[size
];
675 for (int i
= 0; i
< size
; i
++)
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.
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
697 public <S
> S
[] toArray(S
[] a
)
700 a
= (S
[]) Array
.newInstance(a
.getClass().getComponentType(), size
);
701 else if (a
.length
> size
)
704 for (int i
= 0; i
< size
; i
++)
713 * Adds the specified element to the end of the list.
715 * @param value the value to add.
719 public boolean offer(T value
)
725 * Returns the first element of the list without removing
728 * @return the first element of the list.
729 * @throws NoSuchElementException if the list is empty.
738 * Returns the first element of the list without removing
741 * @return the first element of the list, or <code>null</code>
742 * if the list is empty.
753 * Removes and returns the first element of the list.
755 * @return the first element of the list, or <code>null</code>
756 * if the list is empty.
763 return removeFirst();
767 * Removes and returns the first element of the list.
769 * @return the first element of the list.
770 * @throws NoSuchElementException if the list is empty.
775 return removeFirst();
779 * Serializes this object to the given stream.
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
786 private void writeObject(ObjectOutputStream s
) throws IOException
788 s
.defaultWriteObject();
793 s
.writeObject(e
.data
);
799 * Deserializes this object from the given stream.
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
807 private void readObject(ObjectInputStream s
)
808 throws IOException
, ClassNotFoundException
810 s
.defaultReadObject();
813 addLastEntry(new Entry
<T
>((T
) s
.readObject()));
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.
820 * @author Original author unknown
821 * @author Eric Blake (ebb9@email.byu.edu)
823 private final class LinkedListItr
<I
>
824 implements ListIterator
<I
>
826 /** Number of modifications we know about. */
827 private int knownMod
= modCount
;
829 /** Entry that will be returned by next(). */
830 private Entry
<I
> next
;
832 /** Entry that will be returned by previous(). */
833 private Entry
<I
> previous
;
835 /** Entry that will be affected by remove() or set(). */
836 private Entry
<I
> lastReturned
;
838 /** Index of `next'. */
839 private int position
;
842 * Initialize the iterator.
844 * @param index the initial index
846 LinkedListItr(int index
)
851 previous
= (Entry
<I
>) last
;
855 next
= (Entry
<I
>) getEntry(index
);
856 previous
= next
.previous
;
862 * Checks for iterator consistency.
864 * @throws ConcurrentModificationException if the list was modified
866 private void checkMod()
868 if (knownMod
!= modCount
)
869 throw new ConcurrentModificationException();
873 * Returns the index of the next element.
875 * @return the next index
877 public int nextIndex()
883 * Returns the index of the previous element.
885 * @return the previous index
887 public int previousIndex()
893 * Returns true if more elements exist via next.
895 * @return true if next will succeed
897 public boolean hasNext()
899 return (next
!= null);
903 * Returns true if more elements exist via previous.
905 * @return true if previous will succeed
907 public boolean hasPrevious()
909 return (previous
!= null);
913 * Returns the next element.
915 * @return the next element
916 * @throws ConcurrentModificationException if the list was modified
917 * @throws NoSuchElementException if there is no next
923 throw new NoSuchElementException();
925 lastReturned
= previous
= next
;
926 next
= lastReturned
.next
;
927 return lastReturned
.data
;
931 * Returns the previous element.
933 * @return the previous element
934 * @throws ConcurrentModificationException if the list was modified
935 * @throws NoSuchElementException if there is no previous
940 if (previous
== null)
941 throw new NoSuchElementException();
943 lastReturned
= next
= previous
;
944 previous
= lastReturned
.previous
;
945 return lastReturned
.data
;
949 * Remove the most recently returned element from the list.
951 * @throws ConcurrentModificationException if the list was modified
952 * @throws IllegalStateException if there was no last element
957 if (lastReturned
== null)
958 throw new IllegalStateException();
960 // Adjust the position to before the removed element, if the element
961 // being removed is behind the cursor.
962 if (lastReturned
== previous
)
965 next
= lastReturned
.next
;
966 previous
= lastReturned
.previous
;
967 removeEntry((Entry
<T
>) lastReturned
);
974 * Adds an element between the previous and next, and advance to the next.
976 * @param o the element to add
977 * @throws ConcurrentModificationException if the list was modified
986 Entry
<I
> e
= new Entry
<I
>(o
);
987 e
.previous
= previous
;
990 if (previous
!= null)
993 first
= (Entry
<T
>) e
;
1001 lastReturned
= null;
1005 * Changes the contents of the element most recently returned.
1007 * @param o the new element
1008 * @throws ConcurrentModificationException if the list was modified
1009 * @throws IllegalStateException if there was no last element
1011 public void set(I o
)
1014 if (lastReturned
== null)
1015 throw new IllegalStateException();
1016 lastReturned
.data
= o
;
1018 } // class LinkedListItr
1021 * Obtain an Iterator over this list in reverse sequential order.
1023 * @return an Iterator over the elements of the list in
1027 public Iterator
<T
> descendingIterator()
1029 return new Iterator
<T
>()
1031 /** Number of modifications we know about. */
1032 private int knownMod
= modCount
;
1034 /** Entry that will be returned by next(). */
1035 private Entry
<T
> next
= last
;
1037 /** Entry that will be affected by remove() or set(). */
1038 private Entry
<T
> lastReturned
;
1040 /** Index of `next'. */
1041 private int position
= size() - 1;
1043 // This will get inlined, since it is private.
1045 * Checks for modifications made to the list from
1046 * elsewhere while iteration is in progress.
1048 * @throws ConcurrentModificationException if the
1049 * list has been modified elsewhere.
1051 private void checkMod()
1053 if (knownMod
!= modCount
)
1054 throw new ConcurrentModificationException();
1058 * Tests to see if there are any more objects to
1061 * @return true if the start of the list has not yet been
1064 public boolean hasNext()
1066 return next
!= null;
1070 * Retrieves the next object from the list.
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.
1082 throw new NoSuchElementException();
1084 lastReturned
= next
;
1085 next
= lastReturned
.previous
;
1086 return lastReturned
.data
;
1090 * Removes the last object retrieved by <code>next()</code>
1091 * from the list, if the list supports object removal.
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
1099 public void remove()
1102 if (lastReturned
== null)
1103 throw new IllegalStateException();
1104 removeEntry(lastReturned
);
1105 lastReturned
= null;
1112 * Inserts the specified element at the front of the list.
1114 * @param value the element to insert.
1118 public boolean offerFirst(T value
)
1125 * Inserts the specified element at the end of the list.
1127 * @param value the element to insert.
1131 public boolean offerLast(T value
)
1137 * Returns the first element of the list without removing
1140 * @return the first element of the list, or <code>null</code>
1141 * if the list is empty.
1144 public T
peekFirst()
1150 * Returns the last element of the list without removing
1153 * @return the last element of the list, or <code>null</code>
1154 * if the list is empty.
1165 * Removes and returns the first element of the list.
1167 * @return the first element of the list, or <code>null</code>
1168 * if the list is empty.
1171 public T
pollFirst()
1177 * Removes and returns the last element of the list.
1179 * @return the last element of the list, or <code>null</code>
1180 * if the list is empty.
1187 return removeLast();
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()}.
1195 * @return the top of the stack, which is the first element
1197 * @throws NoSuchElementException if the list is empty.
1199 * @see #removeFirst()
1203 return removeFirst();
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)}.
1211 * @param value the element to push on to the stack.
1212 * @throws NoSuchElementException if the list is empty.
1216 public void push(T value
)
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)}.
1227 * @param o the element to remove.
1228 * @return true if an instance of the object was removed.
1231 public boolean removeFirstOccurrence(Object o
)
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.
1241 * @param o the element to remove.
1242 * @return true if an instance of the object was removed.
1245 public boolean removeLastOccurrence(Object o
)
1250 if (equals(o
, e
.data
))