1. 程式人生 > >JDK 1.8 源碼解析 PriorityQueue

JDK 1.8 源碼解析 PriorityQueue

last 數組 guarantee exceptio bre 叠代器 checked continue ole

  

package java.util;

public class PriorityQueue<E> extends AbstractQueue<E>
    implements java.io.Serializable

// 序列化版本號
private static final long serialVersionUID = -7720805057305804111L;

// 默認初始容量
private static final int DEFAULT_INITIAL_CAPACITY = 11;

// 隊列數組
transient Object[] queue; //
non-private to simplify nested class access

// 隊列中元素數量
private int size = 0;

1 // 比較器
2 private final Comparator<? super E> comparator;

// 修改次數
transient int modCount = 0; // non-private to simplify nested class access

// 無參構造方法
public PriorityQueue() {
    this(DEFAULT_INITIAL_CAPACITY, null
); }

// 初始容量作為參數的構造方法
public PriorityQueue(int initialCapacity) {
    this(initialCapacity, null);
}

// 比較器作為參數的構造方法
public PriorityQueue(Comparator<? super E> comparator) {
    this(DEFAULT_INITIAL_CAPACITY, comparator);
}

 1 // 初始容量和比較器作為參數的構造方法
 2 public PriorityQueue(int initialCapacity,
3 Comparator<? super E> comparator) { 4 // Note: This restriction of at least one is not actually needed, 5 // but continues for 1.5 compatibility 6 if (initialCapacity < 1) 7 throw new IllegalArgumentException(); 8 this.queue = new Object[initialCapacity]; 9 this.comparator = comparator; 10 }

 1 // 集合對象作為參數的構造方法
 2 @SuppressWarnings("unchecked")
 3 public PriorityQueue(Collection<? extends E> c) {
 4     if (c instanceof SortedSet<?>) {
 5         SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
 6         this.comparator = (Comparator<? super E>) ss.comparator();
 7         initElementsFromCollection(ss);
 8     }
 9     else if (c instanceof PriorityQueue<?>) {
10         PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
11         this.comparator = (Comparator<? super E>) pq.comparator();
12         initFromPriorityQueue(pq);
13     }
14     else {
15         this.comparator = null;
16         initFromCollection(c);
17     }
18 }

1 // 優先隊列對象作為參數的構造方法
2 @SuppressWarnings("unchecked")
3 public PriorityQueue(PriorityQueue<? extends E> c) {
4     this.comparator = (Comparator<? super E>) c.comparator();
5     initFromPriorityQueue(c);
6 }

1 // 根據優先隊列對象參數初始化
2 private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
3     if (c.getClass() == PriorityQueue.class) {
4         this.queue = c.toArray();
5         this.size = c.size();
6     } else {
7         initFromCollection(c);
8     }
9 }

 1 // 根據集合對象參數初始化
 2 private void initElementsFromCollection(Collection<? extends E> c) {
 3     Object[] a = c.toArray();
 4     // If c.toArray incorrectly doesn‘t return Object[], copy it.
 5     // 確保實際類型是Object對象數組
 6     if (a.getClass() != Object[].class)
 7         a = Arrays.copyOf(a, a.length, Object[].class);
 8     int len = a.length;
 9     if (len == 1 || this.comparator != null)
10         for (int i = 0; i < len; i++)
11             if (a[i] == null)
12                 throw new NullPointerException();
13     this.queue = a;
14     this.size = a.length;
15 }

1 // 根據集合對象參數初始化
2 private void initFromCollection(Collection<? extends E> c) {
3     initElementsFromCollection(c);
4     heapify();
5 }

// 可分配的數組最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

 1 // 擴容
 2 private void grow(int minCapacity) {
 3     int oldCapacity = queue.length;
 4     // Double size if small; else grow by 50%
 5     int newCapacity = oldCapacity + ((oldCapacity < 64) ?
 6                                      (oldCapacity + 2) :
 7                                      (oldCapacity >> 1));
 8     // overflow-conscious code
 9     if (newCapacity - MAX_ARRAY_SIZE > 0)
10         newCapacity = hugeCapacity(minCapacity);
11     queue = Arrays.copyOf(queue, newCapacity);
12 }

1 // 處理超限容量
2 private static int hugeCapacity(int minCapacity) {
3     if (minCapacity < 0) // overflow
4         throw new OutOfMemoryError();
5     return (minCapacity > MAX_ARRAY_SIZE) ?
6         Integer.MAX_VALUE :
7         MAX_ARRAY_SIZE;
8 }

// 增加一個元素
public boolean add(E e) {
    return offer(e);
}

 1 // 插入元素
 2 public boolean offer(E e) {
 3     // 增加的元素不允許為空
 4     if (e == null)
 5         throw new NullPointerException();
 6     modCount++;
 7     int i = size;
 8     if (i >= queue.length)
 9         grow(i + 1);
10     size = i + 1;
11     if (i == 0)
12         queue[0] = e;
13     else
14         siftUp(i, e);
15     return true;
16 }

1 // 獲取第一個元素
2 @SuppressWarnings("unchecked")
3 public E peek() {
4     return (size == 0) ? null : (E) queue[0];
5 }

1 // 查找某個元素所在的位置
2 private int indexOf(Object o) {
3     if (o != null) {
4         for (int i = 0; i < size; i++)
5             if (o.equals(queue[i]))
6                 return i;
7     }
8     return -1;
9 }

 1 // 刪除某個元素
 2 public boolean remove(Object o) {
 3     int i = indexOf(o);
 4     if (i == -1)
 5         return false;
 6     else {
 7         removeAt(i);
 8         return true;
 9     }
10 }

 1 // 刪除與引用參數指向相同對象的元素
 2 boolean removeEq(Object o) {
 3     for (int i = 0; i < size; i++) {
 4         if (o == queue[i]) {
 5             removeAt(i);
 6             return true;
 7         }
 8     }
 9     return false;
10 }

// 判斷是否包含某個元素
public boolean contains(Object o) {
    return indexOf(o) != -1;
}

// 獲取包含此隊列所有元素的數組
public Object[] toArray() {
    return Arrays.copyOf(queue, size);
}

 1 // 獲取包含此隊列所有元素的數組,返回數組的運行時類型是指定數組的類型
 2 @SuppressWarnings("unchecked")
 3 public <T> T[] toArray(T[] a) {
 4     final int size = this.size;
 5     if (a.length < size)
 6         // Make a new array of a‘s runtime type, but my contents:
 7         return (T[]) Arrays.copyOf(queue, size, a.getClass());
 8     System.arraycopy(queue, 0, a, 0, size);
 9     if (a.length > size)
10         a[size] = null;
11     return a;
12 }

// 獲取叠代器
public Iterator<E> iterator() {
    return new Itr();
}

// 獲取隊列中元素數量
public int size() {
    return size;
}

1 // 刪除隊列中的所有元素
2 public void clear() {
3     modCount++;
4     for (int i = 0; i < size; i++)
5         queue[i] = null;
6     size = 0;
7 }

 1 // 獲取並刪除隊列中的第一個元素
 2 @SuppressWarnings("unchecked")
 3 public E poll() {
 4     if (size == 0)
 5         return null;
 6     int s = --size;
 7     modCount++;
 8     E result = (E) queue[0];
 9     E x = (E) queue[s];
10     queue[s] = null;
11     // 如果還存在元素,需要從根開始向下調整堆
12     if (s != 0)
13         siftDown(0, x);
14     return result;
15 }

 1 // 刪除i位置的元素
 2 @SuppressWarnings("unchecked")
 3 private E removeAt(int i) {
 4     // assert i >= 0 && i < size;
 5     modCount++;
 6     int s = --size;
 7     // 如果刪除的是最後一個元素
 8     if (s == i) // removed last element
 9         queue[i] = null;
10     else {
11         // 默認刪除最後一個元素
12         E moved = (E) queue[s];
13         queue[s] = null;
14         // 置換最後一個元素與要刪除的元素,向下調整堆
15         siftDown(i, moved);
16         // 如果最後一個元素是子堆最值
17         if (queue[i] == moved) {
18             // 向上調整堆
19             siftUp(i, moved);
20             if (queue[i] != moved)
21                 return moved;
22         }
23     }
24     return null;
25 }

1 // 向上調整堆
2 private void siftUp(int k, E x) {
3     if (comparator != null)
4         siftUpUsingComparator(k, x);
5     else
6         siftUpComparable(k, x);
7 }

 1 // 不使用比較器來調整堆
 2 @SuppressWarnings("unchecked")
 3 private void siftUpComparable(int k, E x) {
 4     Comparable<? super E> key = (Comparable<? super E>) x;
 5     while (k > 0) {
 6         int parent = (k - 1) >>> 1;
 7         Object e = queue[parent];
 8         if (key.compareTo((E) e) >= 0)
 9             break;
10         queue[k] = e;
11         k = parent;
12     }
13     queue[k] = key;
14 }

 1 // 使用比較器來調整堆
 2 @SuppressWarnings("unchecked")
 3 private void siftUpUsingComparator(int k, E x) {
 4     while (k > 0) {
 5         int parent = (k - 1) >>> 1;
 6         Object e = queue[parent];
 7         if (comparator.compare(x, (E) e) >= 0)
 8             break;
 9         queue[k] = e;
10         k = parent;
11     }
12     queue[k] = x;
13 }

1 // 向下調整堆
2 private void siftDown(int k, E x) {
3     if (comparator != null)
4         siftDownUsingComparator(k, x);
5     else
6         siftDownComparable(k, x);
7 }

 1 // 不使用比較器來調整堆
 2 @SuppressWarnings("unchecked")
 3 private void siftDownComparable(int k, E x) {
 4     Comparable<? super E> key = (Comparable<? super E>)x;
 5     // 獲取邊界
 6     int half = size >>> 1;        // loop while a non-leaf
 7     while (k < half) {
 8         // 獲取左孩子位置
 9         int child = (k << 1) + 1; // assume left child is least
10         Object c = queue[child];
11         // 獲取右孩子位置
12         int right = child + 1;
13         // 如果右孩子存在並且更大
14         if (right < size &&
15             ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
16             c = queue[child = right];
17         if (key.compareTo((E) c) <= 0)
18             break;
19         queue[k] = c;
20         k = child;
21     }
22     queue[k] = key;
23 }

 1 // 使用比較器來調整堆
 2 @SuppressWarnings("unchecked")
 3 private void siftDownUsingComparator(int k, E x) {
 4     int half = size >>> 1;
 5     while (k < half) {
 6         int child = (k << 1) + 1;
 7         Object c = queue[child];
 8         int right = child + 1;
 9         if (right < size &&
10             comparator.compare((E) c, (E) queue[right]) > 0)
11             c = queue[child = right];
12         if (comparator.compare(x, (E) c) <= 0)
13             break;
14         queue[k] = c;
15         k = child;
16     }
17     queue[k] = x;
18 }

1 // 通過初始化構成堆
2 @SuppressWarnings("unchecked")
3 private void heapify() {
4     for (int i = (size >>> 1) - 1; i >= 0; i--)
5         siftDown(i, (E) queue[i]);
6 }

// 獲取用於排序的比較器
public Comparator<? super E> comparator() {
    return comparator;
}

 1 // 序列化時寫入對象
 2 private void writeObject(java.io.ObjectOutputStream s)
 3     throws java.io.IOException {
 4     // Write out element count, and any hidden stuff
 5     s.defaultWriteObject();
 6 
 7     // Write out array length, for compatibility with 1.5 version
 8     // 數組長度+1表示包括自身的數據量
 9     s.writeInt(Math.max(2, size + 1));
10 
11     // Write out all elements in the "proper order".
12     for (int i = 0; i < size; i++)
13         s.writeObject(queue[i]);
14 }

 1 // 反序列化時讀取對象
 2 private void readObject(java.io.ObjectInputStream s)
 3     throws java.io.IOException, ClassNotFoundException {
 4     // Read in size, and any hidden stuff
 5     s.defaultReadObject();
 6 
 7     // Read in (and discard) array length
 8     s.readInt();
 9 
10     queue = new Object[size];
11 
12     // Read in all elements.
13     for (int i = 0; i < size; i++)
14         queue[i] = s.readObject();
15 
16     // Elements are guaranteed to be in "proper order", but the
17     // spec has never explained what that might be.
18     heapify();
19 }

JDK 1.8 源碼解析 PriorityQueue