remove()和poll()方法删除并返回队列的头部。
element()和peek()方法返回,但不删除队列的头部。
从第二点开始,它说方法peek()
返回队列的head元素,那么在下面的程序中它是如何返回队列的head元素的呢?
public class PQ {
public static void main(String[] args) {
PriorityQueue<String> pq = new PriorityQueue<String>();
pq.add("carrot");
pq.add("apple");
pq.add("banana");
System.out.println(pq.poll() + ":" + pq.peek()); // prints apple and banana rather than apple and apple
}
}
一旦删除了第一个元素(胡萝卜),apple就会成为队列的头部(根据队列中的FIFO),所以peek()方法应该返回苹果吗?
例2:
public class PQ {
public static void main(String[] args) {
PriorityQueue<String> pq = new PriorityQueue<String>();
pq.add("carrot");
pq.add("apple");
pq.add("banana");
System.out.println(pq); // prints [apple, carrot, banana] -> it should be [apple, banana, carrot] right? if it is following natural sorting order
}
}
答案 0 :(得分:8)
因为你是第一次投票
System.out.println(pq.poll() + ":" + pq.peek());
由于它是优先级队列元素存储为
carrot -> banana -> apple
当您poll()
获得apple
并从队列中删除时。在此之后,队列头部为banana
,这正是您peek()
时获得的。
请在更新的问题中查看示例2。排序很奇怪
这正是你所期待的。您可以看到documentation
方法iterator()中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray())。
如果您读取java优先级队列使用的优先级堆数据结构,您将更好地理解这一点。您应该使用poll(), peek()
方法来获取有序数据。
答案 1 :(得分:2)
您正在使用PriorityQueue而不是java.util.Queue(常规队列) PriorityQueue根据Comparable :: compareTo()方法的实现对元素进行排序,该方法是String.class的自然排序(字母顺序)。
因此,队列中的元素将是apple-banana-carrot。 输出符合预期
答案 2 :(得分:2)
您已通过引用文档自行回答了问题。
您的优先级队列包含
apple, banana, carrot
poll
返回“apple”然后删除它。所以队列现在是
banana, carrot
peek
然后返回“banana”
答案 3 :(得分:2)
POLL()方法将从队列中删除该元素并将元素返回到调用方法。 PEEK()方法只返回该元素。 参考POLL()和PEEK()方法的实现代码:
public E poll() {
if (this.size == 0)
return null;
int i = --this.size;
this.modCount += 1;
Object localObject1 = this.queue[0];
Object localObject2 = this.queue[i];
this.queue[i] = null;
if (i != 0)
siftDown(0, localObject2);
return localObject1;
}
public E peek() {
return ((this.size == 0) ? null : this.queue[0]);
}
答案 4 :(得分:2)
Queue接口定义了一些处理列表第一个元素的方法,这些方法的行为方式不同。这些方法是:
peek()
element()
poll()
remove()
peek()此方法检索队列的第一个元素的值,而不将其从队列中删除。对于方法的每次调用,我们总是得到相同的值,并且它的执行不会影响队列的大小。如果队列为空,则peek()方法返回null。
元素()此方法的行为类似于peek(),因此它再次检索第一个元素的值而不删除它。但是,如果列表为空,则element()会抛出NoSuchElementException。
poll()此方法通过从队列中删除队列的第一个元素来检索该值。 。在每次调用时,它都会删除列表的第一个元素,如果列表已经为空,则返回null,但不会抛出任何异常。
remove()此方法的行为与poll()方法相同,因此它会删除列表的第一个元素,如果列表为空,则会抛出NoSuchElementException