从Java中的PriorityQueue中间检索项目

时间:2015-05-30 20:08:32

标签: java priority-queue

给出以下代码:

import java.util.*;

class SimpleTest {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        pq.add(1);
        pq.add(2);
        pq.add(3);
        pq.add(4);
        pq.add(5);
        pq.add(6);
        pq.add(7);

        int index = 0;
        int middleNumber = 0;
        Iterator it = pq.iterator();

        //Is number odd
        if(pq.size() % 2 != 0) {
            System.out.println(pq.size());

            //keep removing from queue until we reached queueSize/2 (rounded up)
            while(it.hasNext() && index++ <= ((pq.size() >> 1) + 1)) {
                middleNumber = pq.poll();
            }
            System.out.println("The middle number is: " + (float)middleNumber);
        }       

    }
}

这适用于一些奇数,但不适用于其他数字,我不明白为什么。

给定7个项目的队列,上面的代码返回4,它位于队列的中间。

但是如果我尝试一个包含9个元素的队列(1-9)。当它应为5时,它也返回4。

为什么会这样?

2 个答案:

答案 0 :(得分:1)

主要问题是这一行:

                middleNumber = pq.poll();

减小队列的大小,这会影响该行的含义:

            while(it.hasNext() && index++ <= ((pq.size() >> 1) + 1)) {

然后存在次要问题 - while表达式写错了 - 我认为是因为你试图调整while以适用于队列以7个元素开头的情况,而不是了解潜在的错误。

相反,您应该预先计算所需的索引,然后轮询到该点:

int indexOfMiddleNumber = pq.size() / 2;
for (int index = 0; index < indexOfMiddleNumber; ++index) {
    pq.poll();
}
int middleNumber = pq.poll();

(注意迭代器没有用,在一个也在修改底层集合的循环中调用it.hasNext()实际上是一个非常糟糕的主意。我很惊讶PriorityQueue不是为此提供ConcurrentModificationException。)

答案 1 :(得分:-1)

PriorityQueue的迭代器不按优先级顺序迭代,只是以底层集合的自然顺序。见Javadoc。

获得优先顺序的唯一方法是致电PriorityQueue.remove().