为什么Java中的PriorityQueue不能具有initialCapacity 0?

为什么Java中的PriorityQueue不能具有initialCapacity 0?,java,data-structures,collections,Java,Data Structures,Collections,我使用PriorityQueue对一些数据进行部分排序。特别是,以下代码: Collection<Data> data = ...; PriorityQueue<Data> queue = new PriorityQueue<Data>(data.size(), dataComparator); queue.addAll(data); // iterate over queue with remove() until we have as much data

我使用
PriorityQueue
对一些数据进行部分排序。特别是,以下代码:

Collection<Data> data = ...;
PriorityQueue<Data> queue = new PriorityQueue<Data>(data.size(), dataComparator);
queue.addAll(data);
// iterate over queue with remove() until we have as much data as we need or until queue is empty
收集数据=。。。; PriorityQueue=新的PriorityQueue(data.size(),dataComparator); queue.addAll(数据); //使用remove()遍历队列,直到获得所需的数据或队列为空 不幸的是,当
数据
收集为空时,代码失败,因为
优先级队列
不能作为初始容量传递零。这一设计决策背后的原因是什么?为什么不能有一个0大小的
PriorityQueue


UPD:我知道如何解决这个问题。我想知道为什么
PriorityQueue
不在其中包含这个max(1,n)代码-有什么原因吗?或者这只是一个糟糕的API设计吗?

如果您认为需要容量意味着,它意味着准备队列能够存储至少X个项目,而不需要额外的内部内存分配。因此,如果您希望一个队列最多包含100个项目,那么可以在构造函数中将容量设置为100,以便为此做好准备


告诉队列不需要任何项目有什么意义?首先允许0是没有意义的,因此最小值是1,如果传递0(或更少),构造函数将抛出异常。

为什么要创建集合,但指定它应该为空

您可以使用
Math.max(1,data.size())实例化PriorityQueue

您可以使用它来避免IllegalArgumentException

public PriorityQueue(Collection<? extends E> c)

public PriorityQueue(来自PriorityQueue源代码的集合:

/**
* Priority queue represented as a balanced binary heap: the two children
* of queue[n] are queue[2*n] and queue[2*n + 1]. The priority queue is
* ordered by comparator, or by the elements' natural ordering, if
* comparator is null: For each node n in the heap and each descendant d
* of n, n <= d.
*
* The element with the lowest value is in queue[1], assuming the queue is
* nonempty. (A one-based array is used in preference to the traditional
* zero-based array to simplify parent and child calculations.)
*
* queue.length must be >= 2, even if size == 0.
*/
/**
*表示为平衡二进制堆的优先级队列:两个子级
*队列[n]的优先级为队列[2*n]和队列[2*n+1]。优先级为
*按比较器排序,或按元素的自然顺序排序,如果
*比较器为空:对于堆中的每个节点n和每个子节点d
*对于n,n=2,即使大小=0。
*/

阅读更多信息:

为什么要使用队列?队列是一种数据结构,适用于“生产者”对项目进行排队,以及“消费者”的情况优先级队列使用树状结构对排队的项目进行排序。生产者需要缓冲区才能排队,因此
initialCapacity=0
毫无意义

在您的情况下您从不将任何内容排队,您只需处理已有集合中的数据。为什么要为其创建新的数据结构?您可以使用

for (Data item : Collections.sort(data, dataComparator)) {
    // ...
}


,在Daniel的评论之后,使用,这样您就可以从您实际只需要一部分项目的情况中获益。

您所说的“代码失败”是什么意思?具体发生了什么?PriorityQueue构造函数将抛出一个IllegalArgumentException,请务必询问Joshua Bloch()精英先生:你认为他会回答吗?你的例子听起来很好,但是开发人员怎么知道他写代码时会有100个项目呢?他通常会想到“n”,而n=0是很正常的情况。@chiccodoro:通常你可以从其他数据中得到n的近似值。如果不能,那没关系。这只是一个提示。如果太小,队列会自动调整大小。@chiccodoro,100个项目是容量,而不是将要存储的项目数。不要应用你的经验对于其他所有人来说。许多问题都有一个有限的输入域,因此在许多情况下,开发人员对他们可能需要的容量有一个非常好的想法。而且,n=0可能是一种正常的情况,但这是一种你根本不会使用容器的情况,那么为什么要对此大惊小怪呢?@mikerobi:你说得对,你不会这么做要使用容器。问题是,如果n可以是0…xyz中的任何值,那么写“n”比写“Math.min(n,1)”更舒服@locka,事实上,我确切地知道队列将存储多少项——和我要排序的集合一样多。但有时候这个集合是空的。我假设他使用了另一个构造函数,因为这是传递特殊比较器的唯一方法。@Péter Török:啊,没错。那是一个比较器,而不是集合。我看错了。我编辑了我的答案以反映这一点。我使用它来进行/partial/sort。我可能有很多数据元素,但我只需要选择前10个左右,而不需要对其余的进行排序。你必须对所有元素进行排序,以获得前10个。(+1用于理解问题)在O(n)中很容易获得集合的前k个元素排序时,通常需要时间(在日志n上).CLRS commnet,wikipedia对此提供了非常好的参考:。对于并行/分布式处理,有Map/Reduce技术:@Daniel:这是一个非常好的提示!但是如果Shooshpanchick实际上不需要精确的10个元素,而是在每个项目决定是否需要另一个元素之后,我担心这不会不幸的是,我不再使用O(n)了。对吗?
PriorityQueue
javadoc明确地说
remove()
O(log(n))
。这意味着无论我是否知道需要多少元素,检索第一个k都将是O(klog(n)),这比O(nlog(n))好对于排序。我在初始集合上进行了几次转换,我不想在它为空的情况下编写单独的代码。代码越少越好。它描述了队列内部的工作方式,我正在询问它的API。API是PriorityQueue数据结构的实现,所以本质上,@stark是正确的。这仍然是正确的精英先生:不管实现是什么,构造函数都可以允许值0..n,这只是为了同质性。实际上,理想的解决方法是允许创建一个优先级队列(集合,构造函数)。我同意这实际上并不能回答问题,我认为
for (Data item : Collections.sort(data, dataComparator)) {
    // ...
}