--- jsr166/src/main/java/util/LinkedList.java 2003/05/14 21:30:44 1.1
+++ jsr166/src/main/java/util/LinkedList.java 2003/11/17 08:09:34 1.13
@@ -1,14 +1,13 @@
/*
- * @(#)LinkedList.java 1.43 01/12/03
+ * %W% %E%
*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.util;
/**
- * JSR166: Added Queue operations.
* Linked list implementation of the List interface. Implements all
* optional list operations, and permits all elements (including
* null). In addition to implementing the List interface,
@@ -17,14 +16,16 @@ package java.util;
* beginning and end of the list. These operations allow linked lists to be
* used as a stack, queue, or double-ended queue (deque).
*
- * All of the stack/queue/deque operations could be easily recast in terms of
- * the standard list operations. They're included here primarily for
- * convenience, though they may run slightly faster than the equivalent List
- * operations.
+ * The class implements the Queue interface, providing
+ * first-in-first-out queue operations for add,
+ * poll, etc. Other stack and deque operations could be
+ * easily recast in terms of the standard list operations. They're
+ * included here primarily for convenience, though they may run
+ * slightly faster than the equivalent List operations.
*
* All of the operations perform as could be expected for a doubly-linked
* list. Operations that index into the list will traverse the list from
- * the begining or the end, whichever is closer to the specified index.
+ * the beginning or the end, whichever is closer to the specified index.
*
* Note that this implementation is not synchronized. If multiple
* threads access a list concurrently, and at least one of the threads
@@ -51,24 +52,30 @@ package java.util;
*
Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification. Fail-fast iterators
- * throw ConcurrentModificationException on a best-effort basis.
+ * throw ConcurrentModificationException on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: the fail-fast behavior of iterators
- * should be used only to detect bugs.
+ * should be used only to detect bugs.
+ *
+ * This class is a member of the
+ *
+ * Java Collections Framework.
*
* @author Josh Bloch
- * @version 1.43, 12/03/01
- * @see java.util.List
- * @see java.util.ArrayList
- * @see java.util.Vector
- * @see java.util.Collections#synchronizedList(java.util.List)
+ * @version %I%, %G%
+ * @see List
+ * @see ArrayList
+ * @see Vector
+ * @see Collections#synchronizedList(List)
* @since 1.2
+ * @param the type of elements held in this collection
*/
-public class LinkedList extends AbstractSequentialList
- implements List, Queue, Cloneable, java.io.Serializable
+public class LinkedList
+ extends AbstractSequentialList
+ implements List, Queue, Cloneable, java.io.Serializable
{
- private transient Entry header = new Entry(null, null, null);
+ private transient Entry header = new Entry(null, null, null);
private transient int size = 0;
/**
@@ -86,10 +93,10 @@ public class LinkedList extends Abstract
* @param c the collection whose elements are to be placed into this list.
* @throws NullPointerException if the specified collection is null.
*/
- public LinkedList(Collection c) {
- this();
- addAll(c);
- }
+ public LinkedList(Collection extends E> c) {
+ this();
+ addAll(c);
+ }
/**
* Returns the first element in this list.
@@ -97,7 +104,7 @@ public class LinkedList extends Abstract
* @return the first element in this list.
* @throws NoSuchElementException if this list is empty.
*/
- public Object getFirst() {
+ public E getFirst() {
if (size==0)
throw new NoSuchElementException();
@@ -110,7 +117,7 @@ public class LinkedList extends Abstract
* @return the last element in this list.
* @throws NoSuchElementException if this list is empty.
*/
- public Object getLast() {
+ public E getLast() {
if (size==0)
throw new NoSuchElementException();
@@ -123,8 +130,8 @@ public class LinkedList extends Abstract
* @return the first element from this list.
* @throws NoSuchElementException if this list is empty.
*/
- public Object removeFirst() {
- Object first = header.next.element;
+ public E removeFirst() {
+ E first = header.next.element;
remove(header.next);
return first;
}
@@ -135,28 +142,28 @@ public class LinkedList extends Abstract
* @return the last element from this list.
* @throws NoSuchElementException if this list is empty.
*/
- public Object removeLast() {
- Object last = header.previous.element;
+ public E removeLast() {
+ E last = header.previous.element;
remove(header.previous);
return last;
}
/**
* Inserts the given element at the beginning of this list.
- *
+ *
* @param o the element to be inserted at the beginning of this list.
*/
- public void addFirst(Object o) {
+ public void addFirst(E o) {
addBefore(o, header.next);
}
/**
* Appends the given element to the end of this list. (Identical in
* function to the add method; included only for consistency.)
- *
+ *
* @param o the element to be inserted at the end of this list.
*/
- public void addLast(Object o) {
+ public void addLast(E o) {
addBefore(o, header);
}
@@ -189,7 +196,7 @@ public class LinkedList extends Abstract
* @return true (as per the general contract of
* Collection.add).
*/
- public boolean add(Object o) {
+ public boolean add(E o) {
addBefore(o, header);
return true;
}
@@ -206,14 +213,14 @@ public class LinkedList extends Abstract
*/
public boolean remove(Object o) {
if (o==null) {
- for (Entry e = header.next; e != header; e = e.next) {
+ for (Entry e = header.next; e != header; e = e.next) {
if (e.element==null) {
remove(e);
return true;
}
}
} else {
- for (Entry e = header.next; e != header; e = e.next) {
+ for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element)) {
remove(e);
return true;
@@ -235,7 +242,7 @@ public class LinkedList extends Abstract
* @return true if this list changed as a result of the call.
* @throws NullPointerException if the specified collection is null.
*/
- public boolean addAll(Collection c) {
+ public boolean addAll(Collection extends E> c) {
return addAll(size, c);
}
@@ -255,17 +262,20 @@ public class LinkedList extends Abstract
* range (index < 0 || index > size()).
* @throws NullPointerException if the specified collection is null.
*/
- public boolean addAll(int index, Collection c) {
- int numNew = c.size();
+ public boolean addAll(int index, Collection extends E> c) {
+ if (index < 0 || index > size)
+ throw new IndexOutOfBoundsException("Index: "+index+
+ ", Size: "+size);
+ Object[] a = c.toArray();
+ int numNew = a.length;
if (numNew==0)
return false;
modCount++;
- Entry successor = (index==size ? header : entry(index));
- Entry predecessor = successor.previous;
- Iterator it = c.iterator();
+ Entry successor = (index==size ? header : entry(index));
+ Entry predecessor = successor.previous;
for (int i=0; i e = new Entry((E)a[i], successor, predecessor);
predecessor.next = e;
predecessor = e;
}
@@ -292,11 +302,11 @@ public class LinkedList extends Abstract
*
* @param index index of element to return.
* @return the element at the specified position in this list.
- *
+ *
* @throws IndexOutOfBoundsException if the specified index is is out of
* range (index < 0 || index >= size()).
*/
- public Object get(int index) {
+ public E get(int index) {
return entry(index).element;
}
@@ -310,9 +320,9 @@ public class LinkedList extends Abstract
* @throws IndexOutOfBoundsException if the specified index is out of
* range (index < 0 || index >= size()).
*/
- public Object set(int index, Object element) {
- Entry e = entry(index);
- Object oldVal = e.element;
+ public E set(int index, E element) {
+ Entry e = entry(index);
+ E oldVal = e.element;
e.element = element;
return oldVal;
}
@@ -324,11 +334,11 @@ public class LinkedList extends Abstract
*
* @param index index at which the specified element is to be inserted.
* @param element element to be inserted.
- *
+ *
* @throws IndexOutOfBoundsException if the specified index is out of
* range (index < 0 || index > size()).
*/
- public void add(int index, Object element) {
+ public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}
@@ -339,12 +349,12 @@ public class LinkedList extends Abstract
*
* @param index the index of the element to removed.
* @return the element previously at the specified position.
- *
+ *
* @throws IndexOutOfBoundsException if the specified index is out of
* range (index < 0 || index >= size()).
*/
- public Object remove(int index) {
- Entry e = entry(index);
+ public E remove(int index) {
+ Entry e = entry(index);
remove(e);
return e.element;
}
@@ -352,11 +362,11 @@ public class LinkedList extends Abstract
/**
* Return the indexed entry.
*/
- private Entry entry(int index) {
+ private Entry entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
- Entry e = header;
+ Entry e = header;
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
@@ -430,6 +440,62 @@ public class LinkedList extends Abstract
return -1;
}
+ // Queue operations.
+
+ /**
+ * Retrieves, but does not remove, the head (first element) of this list.
+ * @return the head of this queue, or null if this queue is empty.
+ * @since 1.5
+ */
+ public E peek() {
+ if (size==0)
+ return null;
+ return getFirst();
+ }
+
+ /**
+ * Retrieves, but does not remove, the head (first element) of this list.
+ * @return the head of this queue.
+ * @throws NoSuchElementException if this queue is empty.
+ * @since 1.5
+ */
+ public E element() {
+ return getFirst();
+ }
+
+ /**
+ * Retrieves and removes the head (first element) of this list.
+ * @return the head of this queue, or null if this queue is empty.
+ * @since 1.5
+ */
+ public E poll() {
+ if (size==0)
+ return null;
+ return removeFirst();
+ }
+
+ /**
+ * Retrieves and removes the head (first element) of this list.
+ * @return the head of this queue.
+ * @throws NoSuchElementException if this queue is empty.
+ * @since 1.5
+ */
+ public E remove() {
+ return removeFirst();
+ }
+
+ /**
+ * Adds the specified element as the tail (last element) of this list.
+ *
+ * @param o the element to add.
+ * @return true (as per the general contract of
+ * Queue.offer)
+ * @since 1.5
+ */
+ public boolean offer(E o) {
+ return add(o);
+ }
+
/**
* Returns a list-iterator of the elements in this list (in proper
* sequence), starting at the specified position in the list.
@@ -450,15 +516,15 @@ public class LinkedList extends Abstract
* sequence), starting at the specified position in the list.
* @throws IndexOutOfBoundsException if index is out of range
* (index < 0 || index > size()).
- * @see java.util.List#listIterator(int)
+ * @see List#listIterator(int)
*/
- public ListIterator listIterator(int index) {
+ public ListIterator listIterator(int index) {
return new ListItr(index);
}
- private class ListItr implements ListIterator {
- private Entry lastReturned = header;
- private Entry next;
+ private class ListItr implements ListIterator {
+ private Entry lastReturned = header;
+ private Entry next;
private int nextIndex;
private int expectedModCount = modCount;
@@ -481,7 +547,7 @@ public class LinkedList extends Abstract
return nextIndex != size;
}
- public Object next() {
+ public E next() {
checkForComodification();
if (nextIndex == size)
throw new NoSuchElementException();
@@ -496,7 +562,7 @@ public class LinkedList extends Abstract
return nextIndex != 0;
}
- public Object previous() {
+ public E previous() {
if (nextIndex == 0)
throw new NoSuchElementException();
@@ -529,14 +595,14 @@ public class LinkedList extends Abstract
expectedModCount++;
}
- public void set(Object o) {
+ public void set(E o) {
if (lastReturned == header)
throw new IllegalStateException();
checkForComodification();
lastReturned.element = o;
}
- public void add(Object o) {
+ public void add(E o) {
checkForComodification();
lastReturned = header;
addBefore(o, next);
@@ -550,20 +616,20 @@ public class LinkedList extends Abstract
}
}
- private static class Entry {
- Object element;
- Entry next;
- Entry previous;
+ private static class Entry {
+ E element;
+ Entry next;
+ Entry previous;
- Entry(Object element, Entry next, Entry previous) {
+ Entry(E element, Entry next, Entry previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
}
- private Entry addBefore(Object o, Entry e) {
- Entry newEntry = new Entry(o, e, e.previous);
+ private Entry addBefore(E o, Entry e) {
+ Entry newEntry = new Entry(o, e, e.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
@@ -571,7 +637,7 @@ public class LinkedList extends Abstract
return newEntry;
}
- private void remove(Entry e) {
+ private void remove(Entry e) {
if (e == header)
throw new NoSuchElementException();
@@ -588,21 +654,21 @@ public class LinkedList extends Abstract
* @return a shallow copy of this LinkedList instance.
*/
public Object clone() {
- LinkedList clone = null;
- try {
- clone = (LinkedList)super.clone();
- } catch (CloneNotSupportedException e) {
+ LinkedList clone = null;
+ try {
+ clone = (LinkedList) super.clone();
+ } catch (CloneNotSupportedException e) {
throw new InternalError();
}
// Put clone into "virgin" state
- clone.header = new Entry(null, null, null);
+ clone.header = new Entry(null, null, null);
clone.header.next = clone.header.previous = clone.header;
clone.size = 0;
clone.modCount = 0;
// Initialize clone with our elements
- for (Entry e = header.next; e != header; e = e.next)
+ for (Entry e = header.next; e != header; e = e.next)
clone.add(e.element);
return clone;
@@ -618,7 +684,7 @@ public class LinkedList extends Abstract
public Object[] toArray() {
Object[] result = new Object[size];
int i = 0;
- for (Entry e = header.next; e != header; e = e.next)
+ for (Entry e = header.next; e != header; e = e.next)
result[i++] = e.element;
return result;
}
@@ -645,13 +711,14 @@ public class LinkedList extends Abstract
* supertype of the runtime type of every element in this list.
* @throws NullPointerException if the specified array is null.
*/
- public Object[] toArray(Object a[]) {
+ public T[] toArray(T[] a) {
if (a.length < size)
- a = (Object[])java.lang.reflect.Array.newInstance(
+ a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
- for (Entry e = header.next; e != header; e = e.next)
- a[i++] = e.element;
+ Object[] result = a;
+ for (Entry e = header.next; e != header; e = e.next)
+ result[i++] = e.element;
if (a.length > size)
a[size] = null;
@@ -667,9 +734,9 @@ public class LinkedList extends Abstract
*
* @serialData The size of the list (the number of elements it
* contains) is emitted (int), followed by all of its
- * elements (each an Object) in the proper order.
+ * elements (each an Object) in the proper order.
*/
- private synchronized void writeObject(java.io.ObjectOutputStream s)
+ private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
@@ -686,7 +753,7 @@ public class LinkedList extends Abstract
* Reconstitute this LinkedList instance from a stream (that is
* deserialize it).
*/
- private synchronized void readObject(java.io.ObjectInputStream s)
+ private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
@@ -695,44 +762,11 @@ public class LinkedList extends Abstract
int size = s.readInt();
// Initialize header
- header = new Entry(null, null, null);
+ header = new Entry(null, null, null);
header.next = header.previous = header;
// Read in all elements in the proper order.
for (int i=0; i