2010-04-24 10 views
76

Tome la PriorityQueue por ejemplo http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)¿Cuál es la diferencia entre los métodos de agregar y ofrecer en una cola en Java?

¿Puede alguien darme un ejemplo de un Queue donde los métodos add y offer son diferentes?

De acuerdo con el documento Collection, el método add menudo tratará de garantizar que existe un elemento dentro del Collection en lugar de añadir los duplicados. Entonces mi pregunta es, ¿cuál es la diferencia entre los métodos add y offer?

¿Es que el método offer agregará duplicados independientemente? (Dudo que sea porque si un Collection solo tuviera elementos distintos, esto evitaría eso).

EDIT: En un PriorityQueue los métodos add y offer son el mismo método (véase mi respuesta a continuación). ¿Alguien puede darme un ejemplo de una clase donde los métodos add y offer son diferentes?

Respuesta

109

supongo que la diferencia está en el contrato, que cuando elemento no se puede agregar a la colección el método add arroja una excepción y offer no.

Desde: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#add%28E%29

Si una colección niega a añadir un elemento en particular por cualquier motivo aparte de que ya contiene del elemento, debe lanzar una excepción (en lugar de volver falso). Esto preserva la invariante que una colección siempre contiene el elemento especificado después de que esta llamada regresa.

Desde: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Queue.html#offer%28E%29

Inserta el elemento especificado en esta cola, si es posible. Cuando se utiliza colas que pueden imponer inserción restricciones (por ejemplo capacidad límites), oferta método es generalmente preferible método Collection.add (E), que puede dejar de insertar un elemento solamente por lanzar una excepción .

+0

+1 para encontrar ese fragmento sobre cuándo usar 'offer' vs' add'. – Finbarr

19

No hay diferencia para la ejecución de PriorityQueue.add:

public boolean add(E e) { 
    return offer(e); 
} 

Para AbstractQueue realmente hay una diferencia:

public boolean add(E e) { 
    if (offer(e)) 
     return true; 
    else 
     throw new IllegalStateException("Queue full"); 
} 
+0

Lo sé, acabo de publicar esa respuesta a mí mismo hace unos minutos. ¿Conoces alguna clase en la que el método 'add' sea diferente al método' offer'? – Finbarr

+0

@Finbarr: Sí, verifique mi respuesta actualizada –

10

La diferencia entre offer y add se explica por estos dos extractos de las javadocs:

Desde el Collection interfaz:

Si una colección niega a add un elemento en particular por cualquier otra razón que eso ya contiene el elemento, debe lanzar una excepción (en lugar de devolver falso). Esto preserva la invariante de que una colección siempre contiene el elemento especificado después de que esta llamada regrese.

Desde la interfaz Queue

Al utilizar colas que pueden imponer restricciones de inserción (por límites ejemplo de capacidad), el método offer generalmente es preferible método Collection.add(E), que puede dejar de insertar un elemento solamente por tirar una excepción.

PriorityQueue es una aplicación Queue que no impone ninguna restricción de inserción. Por lo tanto, los métodos add y offer tienen la misma semántica.

Por el contrario, ArrayBlockingQueue es una implementación en la que offer y add se comportan de manera diferente, dependiendo de cómo se creó la cola de la cola.

0

Fuente: http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html

El método oferta inserta un elemento, si es posible, de lo contrario volver falsa. Esto difiere del método Collection.add, que no puede agregar un elemento solo lanzando una excepción sin marcar. El método de oferta está diseñado para usarse cuando la falla es una ocurrencia normal, en lugar de excepcional, por ejemplo, en colas de capacidad fija (o "limitada").

6

desde el código fuente en JDK 7 de la siguiente manera:

public boolean add(E e) { 
    if (offer(e)) 
     return true; 
    else 
     throw new IllegalStateException("Queue full"); 
} 

podemos saber fácilmente que la función suma devolverá cierto cuando añadir con éxito un nuevo elemento en la cola, pero lanzar una excepción cuando fracasado.

4

La interfaz Queue especifica que add() arrojará una IllegalStateException si no hay espacio disponible actualmente (y si no, devolver true), mientras que offer() regresará false si el elemento no puede insertarse debido a las restricciones de capacidad.

La razón por la que son iguales en un PriorityQueue es que esta cola se especifica que no tiene límites, es decir, no hay restricciones de capacidad. En el caso de que no haya restricciones de capacidad, los contratos de add() y offer() muestran el mismo comportamiento.

0

Voy a escribir el código de ejemplo de contrato de Java para el método de oferta y agregar el método que muestra cómo difieren.

BlockingQueue<String> queue = new ArrayBlockingQueue<>(2); 
     queue.add("TestQuue1");  
     queue.add("TestQuue2"); 
     queue.add("TestQuue3"); // will throw "java.lang.IllegalStateException: Queue full 

BlockingQueue<String> queue = new ArrayBlockingQueue<>(2); 
     queue.offer("TestQuue1");  
     queue.offer("TestQuue2"); 
     queue.offer("TestQuue3"); // will not throw any exception 
1

La diferencia es el siguiente:

  • oferta método - trata de añadir un elemento a una cola, y devuelve falsa si el elemento no se puede añadir (como en caso de que una cola esté llena), o verdadero si el elemento fue agregado, y no arroja ninguna excepción específica.

  • añadir método - trata de añadir un elemento a una cola, y devuelve falsa si el elemento está ya presente en la cola, o devuelve cierto si se añadió el elemento, y arroja una excepción si la cola está llena.

Cuestiones relacionadas