¿Cuál es la diferencia entre los métodos agregar y ofrecer en una cola en Java?

109

Tome, PriorityQueuepor ejemplo, http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

¿Alguien puede darme un ejemplo de Queuedónde los métodos addy offerson diferentes?

Según el Collectiondocumento, el addmétodo a menudo buscará garantizar que un elemento exista dentro del en Collectionlugar de agregar duplicados. Entonces mi pregunta es, ¿cuál es la diferencia entre los métodos addy offer?

¿Es que el offermétodo agregará duplicados independientemente? (Dudo que sea porque si a Collectionsolo tuviera elementos distintos, esto eludiría eso).

EDITAR: En PriorityQueuelos métodos addy offerson el mismo método (vea mi respuesta a continuación). ¿Alguien puede darme un ejemplo de una clase donde los métodos addy offerson diferentes?

Finbarr
fuente

Respuestas:

148

Supongo que la diferencia está en el contrato, que cuando el elemento no se puede agregar a la colección, el addmétodo lanza una excepción y offerno lo hace.

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

Si una colección se niega a agregar un elemento en particular por cualquier motivo que no sea que ya contiene el elemento, debe lanzar una excepción (en lugar de devolver falso). Esto preserva el invariante de que una colección siempre contiene el elemento especificado después de que esta llamada regrese.

De: 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 utilizan colas que pueden imponer restricciones de inserción (por ejemplo, límites de capacidad), la oferta de método es generalmente preferible al método Collection.add (E), que puede fallar al insertar un elemento solo lanzando una excepción.

DVD
fuente
4
1 para el hallazgo Este recorte sobre cuándo utilizar offervs add.
Finbarr
28

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

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

Porque en AbstractQueuerealidad hay una diferencia:

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");
}
Peter Lang
fuente
Lo sé, yo mismo publiqué esa respuesta hace unos minutos. ¿Conoce alguna clase en la que el addmétodo sea diferente al offermétodo?
Finbarr
13

La diferencia entre offery addse explica por estos dos extractos de los javadocs:

Desde la Collectioninterfaz:

Si una colección se niega a addun elemento en particular por cualquier motivo que no sea que ya contiene el elemento, debe lanzar una excepción (en lugar de devolver falso). Esto preserva el invariante de que una colección siempre contiene el elemento especificado después de que esta llamada regrese.

Desde la Queueinterfaz

Cuando se usan colas que pueden imponer restricciones de inserción (por ejemplo, límites de capacidad), el método offeres generalmente preferible al método Collection.add(E), que puede fallar al insertar un elemento solo lanzando una excepción.

PriorityQueuees una Queueimplementación que no impone restricciones de inserción. Por lo tanto, los métodos addy offertienen la misma semántica.

Por el contrario, ArrayBlockingQueuees una implementación en la que offery se addcomportan de manera diferente, dependiendo de cómo se instancia la cola.

Stephen C
fuente
8

La diferencia es la siguiente:

  • método de oferta : intenta agregar un elemento a una cola y devuelve falso si el elemento no se puede agregar (como en el caso de que una cola esté llena), o verdadero si el elemento se agregó y no arroja ninguna excepción específica .

  • agregar método: intenta agregar un elemento a una cola, devuelve verdadero si el elemento se agregó o arroja una IllegalStateException si no hay espacio disponible actualmente.

Maksym Ovsianikov
fuente
1
el método add nunca devuelve falso si el elemento ya está disponible Queue <String> q = new PriorityQueue <> (); String b = "java"; booleano es1 = q.add (b); booleano is2 = q.add ("java"); booleano es3 = q.add (b); booleano is4 = q.offer ("java"); booleano es5 = q.offer (b); booleano es6 = q.offer (b); System.out.println ("qq ::" + q);
Raj
¡Gracias, Raj! Actualicé mi respuesta anterior. La documentación de Oracle dice: "El método de oferta inserta un elemento si es posible, de lo contrario devuelve falso. Esto difiere del método Collection.add, que puede fallar al agregar un elemento solo lanzando una excepción sin marcar. El método de oferta está diseñado para usarse cuando falla es una ocurrencia normal, más que excepcional, por ejemplo, en colas de capacidad fija (o "limitadas") ".
Maksym Ovsianikov
7

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 agregar devolverá verdadero cuando agregue con éxito un nuevo elemento a la cola, pero lanzará una excepción cuando fallará.

Heavin
fuente
5

La Queueinterfaz especifica que add()arrojará un IllegalStateExceptionsi no hay espacio disponible actualmente (y de lo contrario regresará true) mientras offer()que regresará falsesi el elemento no se pudo insertar debido a restricciones de capacidad.

La razón por la que son iguales en a PriorityQueuees que esta cola se especifica como ilimitada, 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.

Pedro
fuente
2

Escribiré el código de ejemplo del contrato de Java para el método de oferta y agregaré el método que muestra en qué se diferencian.

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
Aslam anwer
fuente
0

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

El método de oferta inserta un elemento si es posible; de ​​lo contrario, devuelve falso. Esto difiere del método Collection.add, que puede fallar al 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, más que excepcional, por ejemplo, en colas de capacidad fija (o "limitadas").

Yeshodhan Kulkarni
fuente