2012-05-06 23 views

Respuesta

9

Aquí es una parte de PriorityQueue Javadoc:

esta cola órdenes de elementos de acuerdo con un orden especificado en el tiempo de construcción, que se especifica ya sea de acuerdo con su orden natural (ver Comparable), o de acuerdo a un comparador, dependiendo de qué constructor se use.

Así que sí, PriorityQueue usa Comparator (si lo especificó como un argumento de constructor) o usa el método compareTo (...) (los elementos deben implementar una interfaz Comparable).

PriorityQueue permite duplicados. Por lo tanto, si desea evitar eso, debe implementar su propia versión de Queue. Puede encontrar una manera muy elegante, cómo hacerlo en "Effective Java", page 85. Alternativamente, puede ampliar la clase PriorityQueue y anular el método add (este es un lugar perfecto para poner contiene (...) check).

4

Un PriorityQueue en Java no tiene ninguna restricción en lo que respecta a duplicar elementos. Si desea asegurarse de que dos elementos idénticos nunca estén presentes en la cola de prioridad al mismo tiempo, la manera más simple sería mantener un Set por separado en paralelo con la cola de prioridad. Cada vez que desee insertar un elemento en la cola de prioridad, puede verificar si el conjunto ya lo contiene, de lo contrario, agréguelo al conjunto y a la cola de prioridad. Siempre que elimine un elemento de la cola de prioridad, simplemente elimine ese elemento del conjunto también.

Alternativamente, dependiendo de las operaciones que pretenda realizar en la cola de prioridad, y cómo se define la igualdad en su caso, podría ser viable reemplazarla por una única TreeSet, ya que eso aún le permitirá realizar todas las operaciones importantes operaciones a las que tendrías acceso en una cola de prioridad mientras que, además, no permite duplicados.

+0

Puede ser útil agregar por qué alguien no usaría un TreeSet. (Las operaciones de exploración en un TreeSet son O (logn) mientras que PriorityQueue es constante; mostrar el encabezado es * ligeramente * más caro en un TreeSet) – JMess

3

Los conjuntos son los únicos elementos que ignoran los duplicados. Las listas y las colas no. (LinkedList es una cola)

Si desea soltar duplicados, puede verificar si la entrada que toma() es la misma que la anterior e ignorarla. Puedes hacer la comparación como quieras. ;)

+1

Para que esto funcione, la función de comparación debe ser consistente con la igualdad, que no siempre es caso. Por ejemplo, una búsqueda A * de múltiples estados, donde la Q de estado abierto se compara con el peso y la igualdad en el nodo, que no están relacionados entre sí. –

+0

@ LaurentGrégoire podría construir tales casos, sin embargo, dado el javadoc de compareTo dice que debe ser consistente con iguales, es un truco bastante serio para no hacer esto. –

5
import java.util.PriorityQueue; 

public class NoDuplicates<E> extends PriorityQueue<E> 
{ 
    @Override 
    public boolean offer(E e) 
    { 
     boolean isAdded = false; 
     if(!super.contains(e)) 
     { 
      isAdded = super.offer(e); 
     } 
     return isAdded; 
    } 
    public static void main(String args[]) 
    { 
     PriorityQueue<Integer> p = new NoDuplicates<Integer>(); 
     p.add(10); 
     p.add(20); 
     p.add(10); 
     for(int i =0;i<=2;i++) 
     { 
      System.out.println(p.poll()); 
     } 

    } 
} 
+10

Teniendo en cuenta que PriorityQueue es un Binary Heap y que su método contains() se ejecuta en O (n), apenas podría pensar en algo más ineficiente que este código. –

Cuestiones relacionadas