Qual è la differenza tra i metodi di aggiunta e offerta in una coda in Java?


109

Prendi PriorityQueuead esempio http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Qualcuno può darmi un esempio di Queuedove i metodi adde offersono diversi?

Secondo il Collectiondocumento, il addmetodo cercherà spesso di garantire che un elemento esista all'interno di Collectionpiuttosto che aggiungere duplicati. Quindi la mia domanda è: qual è la differenza tra i metodi adde offer?

È che il offermetodo aggiungerà i duplicati a prescindere? (Dubito che sia perché se a Collectiondovesse avere solo elementi distinti questo lo aggirerebbe).

EDIT: In un PriorityQueuei metodi adde offersono lo stesso metodo (vedi la mia risposta sotto). Qualcuno può darmi un esempio di una classe in cui i metodi adde offersono diversi?

Risposte:


148

Immagino che la differenza sia nel contratto, che quando l'elemento non può essere aggiunto alla raccolta, il addmetodo genera un'eccezione e offernon lo fa.

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

Se una raccolta rifiuta di aggiungere un particolare elemento per qualsiasi motivo diverso dal fatto che contiene già l'elemento, deve generare un'eccezione (anziché restituire false). Ciò preserva l'invariante secondo cui una raccolta contiene sempre l'elemento specificato dopo la restituzione di questa chiamata.

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

Inserisce l'elemento specificato in questa coda, se possibile. Quando si utilizzano code che possono imporre restrizioni di inserimento (ad esempio limiti di capacità), l'offerta del metodo è generalmente preferibile al metodo Collection.add (E), che può non riuscire a inserire un elemento solo generando un'eccezione.


4
+1 per constatazione che frammento su quando utilizzare offervs add.
Finbarr

28

Non c'è differenza per l'implementazione di PriorityQueue.add:

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

Perché in AbstractQueuerealtà c'è una differenza:

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

Lo so, ho postato quella risposta io stesso pochi minuti fa. Conosci classi in cui il addmetodo è diverso dal offermetodo?
Finbarr

13

La differenza tra offere addè spiegata da questi due estratti dai javadoc:

Dall'interfaccia Collection:

Se una raccolta rifiuta addun particolare elemento per qualsiasi motivo diverso dal fatto che contiene già l'elemento, deve generare un'eccezione (anziché restituire false). Ciò preserva l'invariante secondo cui una raccolta contiene sempre l'elemento specificato dopo la restituzione della chiamata.

Dal Queueinterfaccia

Quando si utilizzano code che possono imporre restrizioni di inserimento (ad esempio limiti di capacità), il metodo offerè generalmente preferibile al metodo Collection.add(E), che può non riuscire a inserire un elemento solo generando un'eccezione.

PriorityQueueè Queueun'implementazione che non impone alcuna restrizione di inserimento. Pertanto i metodi adde offerhanno la stessa semantica.

Al contrario, ArrayBlockingQueueè un'implementazione in cui offere si addcomportano in modo diverso, a seconda di come è stata istanziata la coda.


8

La differenza è la seguente:

  • metodo di offerta : cerca di aggiungere un elemento a una coda e restituisce false se l'elemento non può essere aggiunto (come nel caso in cui una coda è piena) o true se l'elemento è stato aggiunto e non genera alcuna eccezione specifica .

  • metodo add : cerca di aggiungere un elemento a una coda, restituisce true se l'elemento è stato aggiunto o genera un'eccezione IllegalStateException se non è attualmente disponibile spazio.


1
il metodo add non restituisce mai false se l'elemento è già disponibile Queue <String> q = new PriorityQueue <> (); Stringa b = "java"; booleano è 1 = q.add (b); booleano is2 = q.add ("java"); booleano è3 = q.add (b); booleano is4 = q.offer ("java"); booleano is5 = q.offer (b); booleano is6 = q.offer (b); System.out.println ( "qq ::" + q);
Raj

Grazie, Raj! Ho aggiornato la mia risposta sopra. La documentazione Oracle dice: "Il metodo dell'offerta inserisce un elemento se possibile, altrimenti restituisce false. Questo è diverso dal metodo Collection.add, che può non riuscire ad aggiungere un elemento solo generando un'eccezione non selezionata. Il metodo dell'offerta è progettato per essere utilizzato in caso di errore è un evento normale, piuttosto che eccezionale, ad esempio, nelle code a capacità fissa (o "limitate"). "
Maksym Ovsianikov

7

dal codice sorgente in jdk 7 come segue:

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

possiamo facilmente sapere che la funzione add restituirà true quando aggiunge con successo un nuovo elemento alla coda, ma genera un'eccezione se fallisce.


5

L' Queueinterfaccia specifica che add()lancerà un IllegalStateExceptionse nessuno spazio è attualmente disponibile (e altrimenti restituirà true) mentre offer()torneràfalse se l'elemento non può essere inserito a causa di limitazioni di capacità.

Il motivo per cui sono gli stessi in a PriorityQueueè che questa coda è specificata come illimitata, ovvero non ci sono limitazioni di capacità. In caso di nessuna limitazione di capacità, i contratti di add()e offer()mostrano lo stesso comportamento.


2

Scriverò il codice di esempio del contratto Java per il metodo dell'offerta e aggiungerò il metodo che mostra come differiscono.

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

0

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

Il metodo dell'offerta inserisce un elemento se possibile, altrimenti restituisce false. Questo è diverso dal metodo Collection.add, che può non riuscire ad aggiungere un elemento solo generando un'eccezione non controllata. Il metodo di offerta è progettato per essere utilizzato quando l'errore è un evento normale, piuttosto che eccezionale, ad esempio, in code a capacità fissa (o "limitate").

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.