2010-08-31 14 views
5

Yo uso PriorityQueue para la clasificación parcial de algunos datos. En particular, este es el código:¿Por qué PriorityQueue en Java no puede tener initialCapacity 0?

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 

Por desgracia, cuando data colección está vacía, el código de falla, porque PriorityQueue no se puede pasar de cero como initialCapacity. ¿Cuáles son las razones detrás de esta decisión de diseño? ¿Por qué no puede haber un PriorityQueue de 0?

UPD: Sé cómo evitar esto. Me gustaría saber por qué PriorityQueue no incluye este código máximo (1, n). ¿Hay algún motivo o es solo un mal diseño de la API?

+0

¿Qué quiere decir con "el código falla"? ¿Qué pasa exactamente? –

+0

El constructor de PriorityQueue lanzará una IllegalArgumentException, consulte http://download.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html –

+3

Siempre puede preguntar a Joshua Bloch (http: //en.wikipedia .org/wiki/Joshua_Bloch). Él escribió PriorityQueue. –

Respuesta

9

¿Por qué desea utilizar una cola? Una cola es una estructura de datos creada para el caso en el que tiene un "productor" que encola elementos, y un "consumidor" que los quita. Una cola de prioridad ordena los artículos en cola usando una estructura de árbol. Se necesita una memoria intermedia para que un productor pueda enrutar, por lo que initialCapacity = 0 no tiene sentido.

En su caso que datos nunca enqueue nada, sólo de proceso de una colección que ya tiene. ¿Por qué crear una nueva estructura de datos para ello?Se podía utilizar

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

o, siguiendo el comentario de Daniel, utilice el Selection Algorithm para que pueda beneficiarse de su situación que en realidad se necesita solamente un subconjunto de sus artículos.

+1

Lo uso para/parcial/ordenar. Es posible que tenga muchos elementos de datos, pero debo seleccionar solo los 10 primeros o más, no es necesario ordenar el resto. – Fixpoint

+1

Debe ordenarlos todos para obtener los 10 primeros. (+1 para entender el problema) –

+0

Obtener los elementos k superiores de un conjunto se puede hacer fácilmente en el tiempo O (n), mientras que la clasificación, en general, requiere (En el registro n). Comunicados de CLRS en él, y wikipedia da una muy buena referencia sobre el tema: http://en.wikipedia.org/wiki/Selection_algorithm. Para el procesamiento paralelo/distribuido, hay técnicas de Map/Reduce: http://pl.postech.ac.kr/~myson/pastwork/dr.html –

1

Si cree que quiere capacidad significa, significa preparar la cola para poder almacenar al menos X elementos sin requerir asignaciones de memoria interna adicionales. Por lo tanto, si espera que una cola contenga un máximo de 100 elementos, puede establecer la capacidad en 100 en el constructor para prepararse para eso.

¿Cuál es el punto de decirle a una cola que NO se esperan artículos? No tiene sentido permitir 0 en primer lugar, por lo que el valor mínimo es 1 y el constructor arroja una excepción si pasa 0 (o menos).

+1

Su ejemplo suena hermoso, pero ¿cómo debe saber el desarrollador que serán 100 elementos cuando escriba el código? Normalmente piensa en "n", y n being = 0 es una situación bastante normal. – chiccodoro

+1

@chiccodoro: a menudo puede derivar una aproximación de n de otros datos. Y si no puedes, no importa. Esto es solo una pista. Si es demasiado pequeño, la cola se redimensionará. – musiKk

+1

@chiccodoro, 100 artículos es simplemente la capacidad, no la cantidad de artículos que se almacenarán. No aplique su experiencia a todos los demás. Muchos problemas tienen un dominio finito de entradas, por lo que en muchos casos un desarrollador tiene una muy buena idea del tipo de capacidad que podría necesitar. Además, n = 0 podría ser una situación normal, pero es una situación en la que no estarías usando el contenedor, así que ¿por qué hacer un gran alboroto al respecto? – mikerobi

0

¿Por qué querrías crear una Colección pero luego especificar que debería estar vacía?

justo Usted puede crear una instancia del PriorityQueue con Math.max(1, data.size())

+2

Realizo varias transformaciones en la recopilación inicial y no quiero escribir un código separado para el caso cuando está vacío. Cuanto menos código, mejor. – Fixpoint

1

Hay another constructor puede utilizar para evitar la IllegalArgumentException.

public PriorityQueue(Collection<? extends E> c) 

la cola de prioridad tiene una capacidad inicial de 110% del tamaño de la colección especificada o 1 si la colección está vacía.

Si necesita comparador personalizada, puede hacer la llamada de la siguiente manera (de la respuesta de Jon):

PriorityQueue<Data> queue = new PriorityQueue<Data>(Math.max(data.size(), 1), dataComparator); 

Como otros han dicho, no tiene mucho sentido tener una cola con sin capacidad Como tiene que establecer la capacidad mínima en algún lugar (sin duda no desea permitir valores negativos), establecerlo en 1 parece razonable.

+2

Supongo que usa el otro constructor porque esa es la única forma de pasar un Comparador especial. –

+0

@ Péter Török: Ah, eso es correcto. Eso es un comparador, no una Colección. Leí mal. Edité mi respuesta para reflejar eso. –

4

A partir del código fuente para 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. 
*/ 

Leer más: http://kickjava.com/src/java/util/PriorityQueue.java.htm#ixzz0yBp7ocHR

+0

Describe cómo funciona la cola internamente, y estoy preguntando sobre su API. – Fixpoint

+3

-1 para un volcado de comentario oculto –

+0

La API es una implementación de la estructura de datos PriorityQueue, por lo que en esencia, @stark es correcta. –

Cuestiones relacionadas