Why do I get the following result? [duplicate]

走远了吗. 提交于 2019-12-10 15:19:00

问题


I have done the following test to see how a

PriorityBlockingQueue<String> pq = new PriorityBlockingQueue<>(2);
     pq.put("Sing");
     pq.put("Sing2");
     pq.put("Sing3");
     pq.put("Sing4");
     pq.put("Sing10");
     pq.put("Sing11");
     pq.put("Sing12");
     pq.put("Sing13");
     for (String s1: pq)
     {
         System.out.print(s1 +" ");
     }

The result I get is:

 Sing Sing10 Sing11 Sing13 Sing2 Sing3 Sing12 Sing4

Now how the API says it should order them in their natural order if no comparator specified at construction time. Hoever as you can see the result is not ordered at all.

Secondly the initial capacity I set was of 2, why there is such an option if the bound is actually not set? What's the point? I understand that the api specify that it's an unbounded priority queue however why making a constructor taking an initial capacity at all if it cannot set any bound of it?

So basically I have got 2 questions:

1) Why the order of the result above posted does not follow the natural order of the elements?

2) What is the purpose of having a constructor with a parameter "initial capacity" which does not actually set the bound. In the LinkedBlockingQueue it's reasonable as it sets the bound however it does not happen in the PriorityBlockingQueue.

Thanks in advance.


回答1:


The order is guaranteed when you access the head with poll, remove, peek or take for example, but not when you iterate:

The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order.

This will yield the expected output:

String s;
while ((s = pq.poll()) != null) {
    System.out.println(s);
}

outputs:

Sing
Sing10
Sing11
Sing12
Sing13
Sing2
Sing3
Sing4

What is the purpose of having a constructor with a parameter "initial capacity" which does not actually set the bound.

The initial capacity is not a bound. The queue is backed by an array - by setting the initial capacity you can avoid unnecessary array resizing (similarly to ArrayList's constructor).




回答2:


The javadoc says:

The Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).

You will get elements in order when using peek()/poll()/take(). But not when iterating.

To answer your second question: the queue is implemented as an array of objects internally. Setting an initial capacity allows avoiding too many array copies when the queue grows and the number of elements exceeds the capacity. Just like an ArrayList.




回答3:


The initial capacity is the size with which the container storing your elements is initialized with @-). As elements are added, the capacity grows automatically. It depends on the growth policy (defined by the underlying container) what are the costs of extending the size of the container.

PriorityBlockingQueue is an unbounded blocking queue by its definition. The purpose of having such a constructor with a parameter "initial capacity" is to initialize the underlying container with a value which makes sense for the actual use case. This can not be foreseen by the implementor of the PriorityBlockingQueue.

LinkedBlockingQueue is an optionally-bounded blocking queue by its definition. So the parameter has - if set - the function to act as an upper bound.




回答4:


Check this link

The Iterator provided in method iterator() is not guaranteed to traverse the elements of the PriorityBlockingQueue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()). Also, method drainTo can be used to remove some or all elements in priority order and place them in another collection.



来源:https://stackoverflow.com/questions/17726452/why-do-i-get-the-following-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!