Como Queue extends Collection, debería poder iterarlo.
for (Entero iq: queue) arr [i ++] = iq;
Hmm, si @amit tiene razón en que PriorityQueue garantiza la iteración en orden, esto no funcionará.
Sin embargo, otra edición sigue ...
Muchos de nosotros hemos aprendido que PriorityQueue no iterar en orden. Lo cual se debe a que PriorityQueue solo ordena parcialmente los elementos, principalmente rastrea el elemento principal (el menos).
Una propuesta para conservar el PriorityQueue original es hacer una copia, y tomar/drenar de la copia. La otra es hacer una lista a partir de los contenidos (ya que usted sabe el tamaño exacto, creo que una lista de arreglos es la más adecuada) y clasificarla explícitamente.
Supongo que la lista sería más rápida. Sabemos que es O (n log (n)). Ahora, los javadocs PriorityQueue dicen que las adiciones y las eliminaciones son O (log (n)). Y las llamarías N veces, entonces, en teoría, PriorityQueue también es O (n log (n)).
Sin embargo, si utilizar un PriorityQueue fuera más rápido que un ordenamiento para este caso de uso común, iterando sobre una lista ordenada, creo que habría visto muchos artículos de "consejos de rendimiento" que dicen "Use PriorityQueue en lugar de Collections.sort(). " Que no tengo. ¿Los he echado de menos?
De todos modos, el OP podría probar ambos e informar. Sería, para mí, un descubrimiento fascinante y útil si un PriorityQueue fuera más rápido que ordenar una Lista.
Hice algunas pruebas en 1 millón de enteros al azar. El ArrayList ordenado fue aproximadamente 2 veces más rápido que el drenaje de PriorityQueue en mi antiguo escritorio de 7 años, JDK6. El código sigue.
public class StackOverflow2 {
ArrayList<Integer> generateRandomList(int count, int seed) {
ArrayList<Integer> list = new ArrayList<Integer>(count);
Random random = new Random();
random.setSeed(seed);
for (int i=0; i<count; i++)
list.add(Integer.valueOf(random.nextInt()));
return list;
}
long usePriorityQueue(ArrayList<Integer> inList) {
long total = 0;
long start = System.currentTimeMillis();
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(inList);
while (!pq.isEmpty()) {
total += pq.remove(); // do something so HotSpot doesn't optimize this away...
}
long totaltime = System.currentTimeMillis() - start;
System.out.println("usePriorityQueue totaltime = " + totaltime);
return total;
}
long useArrayList(ArrayList<Integer> inList) {
long total = 0;
long start = System.currentTimeMillis();
ArrayList<Integer> list = new ArrayList<Integer>(inList);
Collections.sort(list);
for (Integer iii : list) {
total += iii; // do something
}
long totaltime = System.currentTimeMillis() - start;
System.out.println("useArrayList totaltime = " + totaltime);
return total;
}
public static void main(String[] args) {
StackOverflow2 so2 = new StackOverflow2();
ArrayList<Integer> randoms = so2.generateRandomList(1000000, 123456);
for (int i=0; i<10; i++) {
long upq = so2.usePriorityQueue(randoms);
long ual = so2.useArrayList(randoms);
}
}
}
Debe definir 'mejor enfoque'. ¿Más rápido? ¿mas elegante? ¿código más corto? más espacio eficiente? ...? – amit
@amit: Sí, todo lo que ha dicho, si puede proporcionar alguno de ellos. Por supuesto, elegiré la mejor como respuesta. :) –