public PriorityBlockingQueue(Collection<? extends E> c) {
this.lock = new ReentrantLock();
this.notEmpty = lock.newCondition();
boolean heapify = true; // true if not known to be in heap order
boolean screen = true; // true if must screen for nulls
if (c instanceof SortedSet<?>) {
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
this.comparator = (Comparator<? super E>) ss.comparator();
heapify = false;
}
else if (c instanceof PriorityBlockingQueue<?>) {
PriorityBlockingQueue<? extends E> pq =
(PriorityBlockingQueue<? extends E>) c;
this.comparator = (Comparator<? super E>) pq.comparator();
screen = false;
if (pq.getClass() == PriorityBlockingQueue.class) // exact match 第一处
heapify = false;
}
Object[] a = c.toArray();
int n = a.length;
// If c.toArray incorrectly doesn't return Object[], copy it.
if (a.getClass() != Object[].class) //第二处
a = Arrays.copyOf(a, n, Object[].class);
if (screen && (n == 1 || this.comparator != null)) { //第三处
for (int i = 0; i < n; ++i)
if (a[i] == null)
throw new NullPointerException();
}
this.queue = a;
this.size = n;
if (heapify)
heapify();
}
为什么一定要if (pq.getClass() == PriorityBlockingQueue.class)
才不用重新建堆( heapify 为 false,就不用重新建堆),大概意思就是 PriorityBlockingQueue 的子类可能重写了方法,所以可能 PriorityBlockingQueue 的子类的内部数组根本不是堆吗?
为什么当if (a.getClass() != Object[].class)
时,就一定要新建一个类型为Object[].class
的数组,即使两个数组里面的元素都是一样的。而且意思 c.toArray()返回的实际类型不一定是Object[].class
了呗
if (screen && (n == 1 || this.comparator != null))
时重新检查有没有 null 元素,但是后面的(n == 1 || this.comparator != null)
不是很理解为什么这么判断?
看最近的 jdk 的源码也是这样,http://hg.openjdk.java.net/jdk/jdk15/file/d2c6eb3b2c8d/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java#l242 ,应该不是版本问题。
求大佬们不吝赐教
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.