PriorityQueue
一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。
package com.enterise.always.priorityqueue;
import java.util.PriorityQueue;
import java.util.Random;
public class MainAction {
public static void main(String[] args) {
PriorityQueue<Student> studentQueue = new PriorityQueue<Student>();
for (int i = 0; i < 10; i++) {
System.out.println("i--->>"+i);
studentQueue.add(new Student(new Random().nextInt(100)));
}
int size = studentQueue.size();
for (int j = 0; j < size; j++) {
Student s = studentQueue.poll();
System.out.println("s--->"+s.getId());
}
}
}
add方法介绍:
将指定的元素插入此优先级队列。
ClassCastException - 如果根据优先级队列的顺序无法将指定元素与此优先级队列中当前元素进行比较。
NullPointerException - 如果指定的元素为 null。
所以在add方法中会对要添加的元素进行比较,如果你的优先级比较高,那么就排在前面,反之其然。
那么添加的元素如果不一致,那么就不能进行比较,所以要添加的元素必须实现Comparable接口,或者在构造这个PriorityQueue的时候,要传进一个指定的比较器进行比较。
源码实现是:/**
* Inserts the specified element into this priority queue.
*
* @return {@code true} (as specified by {@link Collection#add})
* @throws ClassCastException if the specified element cannot be
* compared with elements currently in this priority queue
* according to the priority queue's ordering
* @throws NullPointerException if the specified element is null
*/
public boolean add(E e) {
return offer(e);
}
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
modCount++;
int i = size;
if (i >= queue.length)
grow(i + 1);
size = i + 1;
if (i == 0)//刚开始添加没有进行比较。
queue[0] = e;
else
siftUp(i, e);//根据指定的比较器进行比较。
return true;
}
private void siftUp(int k, E x) {//先判断是否构造中有比较器。
if (comparator != null)
siftUpUsingComparator(k, x);
else
siftUpComparable(k, x);
}
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}
所以实现优先级的队列是在内部对其按照指定的构造器进行排列。
poll方法:
获取并移除此队列的头,如果此队列为空,则返回 null。
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}
此对象是线程不安全的,
LinkedBlockingQueue(线程安全)