为什么我得到以下结果?

Rol*_*all 4 java concurrency priority-queue

我做了以下测试,看看如何

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 +" ");
     }
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

 Sing Sing10 Sing11 Sing13 Sing2 Sing3 Sing12 Sing4
Run Code Online (Sandbox Code Playgroud)

现在API如何表示如果在施工时没有指定比较器,它应按自然顺序排序.但是,你可以看到结果根本没有订购.

其次我设置的初始容量是2,为什么有这样的选项,如果绑定实际上没有设置?重点是什么?我知道api指定它是一个无界的优先级队列但是为什么如果构造函数不能设置它的任何约束,那么为什么要使构造函数完全具有初始容量?

所以基本上我有两个问题:

1)为什么上面发布的结果的顺序不符合元素的自然顺序?

2)具有参数"initial capacity"的构造函数的目的是什么,该参数实际上没有设置边界.在LinkedBlockingQueue中,它设置绑定是合理的,但它不会发生在PriorityBlockingQueue中.

提前致谢.

ass*_*ias 10

例如,当您使用poll,remove,peek或take来访问头部时,保证顺序,但是在迭代时不能:

方法iterator()中提供的迭代器不保证以任何特定顺序遍历优先级队列的元素.

这将产生预期的输出:

String s;
while ((s = pq.poll()) != null) {
    System.out.println(s);
}
Run Code Online (Sandbox Code Playgroud)

输出:

Sing
Sing10
Sing11
Sing12
Sing13
Sing2
Sing3
Sing4
Run Code Online (Sandbox Code Playgroud)

具有参数"initial capacity"的构造函数的目的是什么,该参数实际上没有设置边界.

初始容量不受限制.队列由数组支持 - 通过设置初始容量,可以避免不必要的数组大小调整(类似于ArrayList的构造函数).

  • @Rollerball:我的,但这是同样的答案. (3认同)
  • +1不知道.有趣.鉴于队列具体是按优先级顺序排列,我会对迭代做出相同的假设.我敢打赌,这个设计决定造成了大量的错误. (2认同)

JB *_*zet 5

javadoc说:

方法iterator()中提供的迭代器不保证以任何特定顺序遍历PriorityBlockingQueue的元素.如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray()).

使用时,您将按顺序获取元素peek()/poll()/take().但不是在迭代时.

回答第二个问题:队列在内部实现为对象数组.设置初始容量允许在队列增长且元素数量超过容量时避免过多的阵列副本.就像一个ArrayList.