Java 为什么我会得到以下结果?

Java 为什么我会得到以下结果?,java,concurrency,priority-queue,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");

我做了下面的测试,看看

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 +" ");
     }
现在,如果在构建时没有指定比较器,那么该如何按照自然顺序对它们进行排序。正如你所看到的,结果根本不是有序的

其次,我设置的初始容量是2,如果边界实际上没有设置,为什么会有这样一个选项?重点是什么?我知道api指定它是一个无限制的优先级队列,但是如果构造函数不能设置初始容量的任何边界,为什么要让构造函数获取初始容量呢

基本上我有两个问题:

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

2)使用参数“initial capacity”(初始容量)的构造函数的目的是什么,它实际上没有设置边界。在这种情况下,它是合理的,因为它设置了边界,但是它不会发生在PriorityBlockingQueue中

提前感谢。

javadoc说:

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

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


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

例如,当您使用poll、remove、peek或take访问头部时,顺序是有保证的,但当您迭代时,顺序是没有保证的:

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

这将产生预期输出:

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

Sing
Sing10
Sing11
Sing12
Sing13
Sing2
Sing3
Sing4

有一个参数“initial capacity”的构造函数的目的是什么,它实际上并没有设置边界

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

检查此项

方法迭代器()中提供的迭代器不保证 以任何特定方式遍历PriorityBlockingQueue的元素 秩序。如果需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())。此外,还可以使用方法drainTo来移除 按优先顺序排列某些或所有元素,并将它们放置在另一个元素中 收藏


初始容量是存储元素的容器用@-)初始化的大小。随着元素的添加,容量会自动增长。它取决于增长策略(由基础容器定义),扩展容器大小的成本是多少

PriorityBlockingQueue
是一个无边界的阻塞队列。使用带有参数“initialcapacity”的构造函数的目的是用一个对实际用例有意义的值初始化底层容器。
PriorityBlockingQueue
的实现者无法预见这一点


LinkedBlockingQueue
是一个可选的有界阻塞队列。因此,如果设置了参数,函数将作为上限。

字符串的自然顺序是字母顺序。输出是正确的。@RaviThapliyal不是
Sing12
应该介于
Sing11
Sing13
之间。…@RaviThapliyal:仔细看
Sing3 Sing12 Sing4
不是按字母顺序排列的
Sing12
应该介于
Sing11
Sing13
@SteveP.,Russell Uhl:啊,错过了那一个。@assylias那条线索刚刚涵盖了我问题的第一部分。+1不知道。有趣。考虑到队列是按优先级顺序排列的,我会对迭代做同样的假设。我打赌这个设计决定已经引起了一堆错误。@Gray我确实已经看过好几次了。@Gray我也做了同样的假设。从某种程度上说,这很有道理,但是…@assylias问题的第二点呢?我还没有收到完整的回复。@Rolleball:我也是,但答案是一样的。再看一遍。它不是按字典顺序排列的。
Sing3 Sing12 Sing4
不符合顺序。我也没看到。你们都是对的-我删除了第一个问题的错误答案-thanks@Jost那么为什么LinkedBlockingQueue会设置一个绑定?@Rollerball因为PriorityBlockingQueue是一个无限的阻塞队列
Sing
Sing10
Sing11
Sing12
Sing13
Sing2
Sing3
Sing4