--- jsr166/src/main/java/util/PriorityQueue.java 2007/01/07 07:38:27 1.66
+++ jsr166/src/main/java/util/PriorityQueue.java 2012/12/15 22:26:29 1.79
@@ -1,8 +1,26 @@
/*
- * %W% %E%
+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
*/
package java.util;
@@ -38,14 +56,14 @@ package java.util;
* the priority queue in any particular order. If you need ordered
* traversal, consider using {@code Arrays.sort(pq.toArray())}.
*
- *
Note that this implementation is not synchronized.
+ *
Note that this implementation is not synchronized.
* Multiple threads should not access a {@code PriorityQueue}
* instance concurrently if any of the threads modifies the queue.
* Instead, use the thread-safe {@link
* java.util.concurrent.PriorityBlockingQueue} class.
*
*
Implementation note: this implementation provides
- * O(log(n)) time for the enqueing and dequeing methods
+ * O(log(n)) time for the enqueuing and dequeuing methods
* ({@code offer}, {@code poll}, {@code remove()} and {@code add});
* linear time for the {@code remove(Object)} and {@code contains(Object)}
* methods; and constant time for the retrieval methods
@@ -56,10 +74,10 @@ package java.util;
* Java Collections Framework.
*
* @since 1.5
- * @version %I%, %G%
* @author Josh Bloch, Doug Lea
* @param the type of elements held in this collection
*/
+@SuppressWarnings("unchecked")
public class PriorityQueue extends AbstractQueue
implements java.io.Serializable {
@@ -153,17 +171,21 @@ public class PriorityQueue extends Ab
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(Collection extends E> c) {
- initFromCollection(c);
- if (c instanceof SortedSet)
- comparator = (Comparator super E>)
- ((SortedSet extends E>)c).comparator();
- else if (c instanceof PriorityQueue)
- comparator = (Comparator super E>)
- ((PriorityQueue extends E>)c).comparator();
+ if (c instanceof SortedSet>) {
+ SortedSet extends E> ss = (SortedSet extends E>) c;
+ this.comparator = (Comparator super E>) ss.comparator();
+ initElementsFromCollection(ss);
+ }
+ else if (c instanceof PriorityQueue>) {
+ PriorityQueue extends E> pq = (PriorityQueue extends E>) c;
+ this.comparator = (Comparator super E>) pq.comparator();
+ initFromPriorityQueue(pq);
+ }
else {
- comparator = null;
- heapify();
+ this.comparator = null;
+ initFromCollection(c);
}
}
@@ -181,9 +203,10 @@ public class PriorityQueue extends Ab
* @throws NullPointerException if the specified priority queue or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(PriorityQueue extends E> c) {
- comparator = (Comparator super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator super E>) c.comparator();
+ initFromPriorityQueue(c);
}
/**
@@ -199,9 +222,33 @@ public class PriorityQueue extends Ab
* @throws NullPointerException if the specified sorted set or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(SortedSet extends E> c) {
- comparator = (Comparator super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator super E>) c.comparator();
+ initElementsFromCollection(c);
+ }
+
+ private void initFromPriorityQueue(PriorityQueue extends E> c) {
+ if (c.getClass() == PriorityQueue.class) {
+ this.queue = c.toArray();
+ this.size = c.size();
+ } else {
+ initFromCollection(c);
+ }
+ }
+
+ private void initElementsFromCollection(Collection extends E> c) {
+ Object[] a = c.toArray();
+ // If c.toArray incorrectly doesn't return Object[], copy it.
+ if (a.getClass() != Object[].class)
+ a = Arrays.copyOf(a, a.length, Object[].class);
+ int len = a.length;
+ if (len == 1 || this.comparator != null)
+ for (int i = 0; i < len; i++)
+ if (a[i] == null)
+ throw new NullPointerException();
+ this.queue = a;
+ this.size = a.length;
}
/**
@@ -210,34 +257,43 @@ public class PriorityQueue extends Ab
* @param c the collection
*/
private void initFromCollection(Collection extends E> c) {
- Object[] a = c.toArray();
- // If c.toArray incorrectly doesn't return Object[], copy it.
- if (a.getClass() != Object[].class)
- a = Arrays.copyOf(a, a.length, Object[].class);
- queue = a;
- size = a.length;
+ initElementsFromCollection(c);
+ heapify();
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Increases the capacity of the array.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError();
- int oldCapacity = queue.length;
+ int oldCapacity = queue.length;
// Double size if small; else grow by 50%
- int newCapacity = ((oldCapacity < 64)?
- ((oldCapacity + 1) * 2):
- ((oldCapacity / 2) * 3));
- if (newCapacity < 0) // overflow
- newCapacity = Integer.MAX_VALUE;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
+ int newCapacity = oldCapacity + ((oldCapacity < 64) ?
+ (oldCapacity + 2) :
+ (oldCapacity >> 1));
+ // overflow-conscious code
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
+ }
+
/**
* Inserts the specified element into this priority queue.
*
@@ -276,13 +332,11 @@ public class PriorityQueue extends Ab
}
public E peek() {
- if (size == 0)
- return null;
- return (E) queue[0];
+ return (size == 0) ? null : (E) queue[0];
}
private int indexOf(Object o) {
- if (o != null) {
+ if (o != null) {
for (int i = 0; i < size; i++)
if (o.equals(queue[i]))
return i;
@@ -302,13 +356,13 @@ public class PriorityQueue extends Ab
* @return {@code true} if this queue changed as a result of the call
*/
public boolean remove(Object o) {
- int i = indexOf(o);
- if (i == -1)
- return false;
- else {
- removeAt(i);
- return true;
- }
+ int i = indexOf(o);
+ if (i == -1)
+ return false;
+ else {
+ removeAt(i);
+ return true;
+ }
}
/**
@@ -319,8 +373,8 @@ public class PriorityQueue extends Ab
* @return {@code true} if removed
*/
boolean removeEq(Object o) {
- for (int i = 0; i < size; i++) {
- if (o == queue[i]) {
+ for (int i = 0; i < size; i++) {
+ if (o == queue[i]) {
removeAt(i);
return true;
}
@@ -337,7 +391,7 @@ public class PriorityQueue extends Ab
* @return {@code true} if this queue contains the specified element
*/
public boolean contains(Object o) {
- return indexOf(o) != -1;
+ return indexOf(o) != -1;
}
/**
@@ -379,8 +433,7 @@ public class PriorityQueue extends Ab
* The following code can be used to dump the queue into a newly
* allocated array of String:
*
- *
- * String[] y = x.toArray(new String[0]);
+ * {@code String[] y = x.toArray(new String[0]);}
*
* Note that toArray(new Object[0]) is identical in function to
* toArray().
@@ -398,7 +451,7 @@ public class PriorityQueue extends Ab
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(queue, size, a.getClass());
- System.arraycopy(queue, 0, a, 0, size);
+ System.arraycopy(queue, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
@@ -491,7 +544,7 @@ public class PriorityQueue extends Ab
lastRetElt = null;
} else {
throw new IllegalStateException();
- }
+ }
expectedModCount = modCount;
}
}
@@ -537,7 +590,7 @@ public class PriorityQueue extends Ab
* avoid missing traversing elements.
*/
private E removeAt(int i) {
- assert i >= 0 && i < size;
+ // assert i >= 0 && i < size;
modCount++;
int s = --size;
if (s == i) // removed last element
@@ -672,16 +725,14 @@ public class PriorityQueue extends Ab
}
/**
- * Saves the state of the instance to a stream (that
- * is, serializes it).
+ * Saves this queue to a stream (that is, serializes it).
*
* @serialData The length of the array backing the instance is
* emitted (int), followed by all of its elements
* (each an {@code Object}) in the proper order.
- * @param s the stream
*/
private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException{
+ throws java.io.IOException {
// Write out element count, and any hidden stuff
s.defaultWriteObject();
@@ -694,10 +745,7 @@ public class PriorityQueue extends Ab
}
/**
- * Reconstitutes the {@code PriorityQueue} instance from a stream
- * (that is, deserializes it).
- *
- * @param s the stream
+ * Reconstitutes this queue from a stream (that is, deserializes it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
@@ -707,14 +755,14 @@ public class PriorityQueue extends Ab
// Read in (and discard) array length
s.readInt();
- queue = new Object[size];
+ queue = new Object[size];
// Read in all elements.
for (int i = 0; i < size; i++)
queue[i] = s.readObject();
- // Elements are guaranteed to be in "proper order", but the
- // spec has never explained what that might be.
- heapify();
+ // Elements are guaranteed to be in "proper order", but the
+ // spec has never explained what that might be.
+ heapify();
}
}