JDK 1.8 源码解析 PriorityQueue

Posted wjq2017

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK 1.8 源码解析 PriorityQueue相关的知识,希望对你有一定的参考价值。

  

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的主要内容,如果未能解决你的问题,请参考以下文章

JDK 1.8 源码解析 HashSet

JDK 1.8 源码解析 ConcurrentHashMap

JDK 1.8 源码解析 StringStringBuilder和StringBuffer的异同

Java深入研究9HashMap源码解析(jdk 1.8)

JDK1.8JDK1.8集合源码阅读——TreeMap

Objects源码解析