JDK 1.8 源碼解析 PriorityQueue
阿新 • • 發佈:2018-01-13
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