Was ist der Unterschied zwischen den Add- und Offer-Methoden in einer Warteschlange in Java?


109

Nehmen Sie PriorityQueuezum Beispiel http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Kann mir jemand ein Beispiel geben, Queuewo die addund offerMethoden unterschiedlich sind?

Laut dem CollectionDokument versucht die addMethode häufig sicherzustellen, dass ein Element in der vorhanden ist, Collectionanstatt Duplikate hinzuzufügen. Meine Frage ist also, was ist der Unterschied zwischen addund offerMethoden?

Wird die offerMethode unabhängig davon Duplikate hinzufügen? (Ich bezweifle, dass es daran liegt, dass wenn a Collectionnur unterschiedliche Elemente haben sollte, dies das umgehen würde).

EDIT: In a sind PriorityQueuedie addund offerMethoden die gleiche Methode (siehe meine Antwort unten). Kann mir jemand ein Beispiel für eine Klasse geben, in der die Methoden addund offerMethoden unterschiedlich sind?

Antworten:


148

Ich denke, der Unterschied besteht im Vertrag darin, dass die addMethode eine Ausnahme auslöst , wenn ein Element nicht zur Sammlung hinzugefügt werden kann, und offerdies nicht tut.

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

Wenn sich eine Sammlung aus einem anderen Grund als dem, dass sie das Element bereits enthält, weigert, ein bestimmtes Element hinzuzufügen, muss sie eine Ausnahme auslösen (anstatt false zurückzugeben). Dadurch bleibt die Invariante erhalten, dass eine Sammlung nach der Rückkehr dieses Aufrufs immer das angegebene Element enthält.

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

Fügt das angegebene Element nach Möglichkeit in diese Warteschlange ein. Bei Verwendung von Warteschlangen, die Einfügungsbeschränkungen auferlegen können (z. B. Kapazitätsgrenzen), ist das Methodenangebot im Allgemeinen der Methode Collection.add (E) vorzuziehen, bei der ein Element möglicherweise nur durch Auslösen einer Ausnahme nicht eingefügt werden kann.


4
+1, um das Snippet zu finden, wann offervs verwendet werden soll add.
Finbarr

28

Es gibt keinen Unterschied für die Implementierung von PriorityQueue.add:

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

Denn es AbstractQueuegibt tatsächlich einen Unterschied:

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

Ich weiß, ich habe diese Antwort vor ein paar Minuten selbst gepostet. Kennen Sie Klassen, in denen sich die addMethode von der offerMethode unterscheidet?
Finbarr

13

Der Unterschied zwischen offerund addwird durch diese beiden Auszüge aus den Javadocs erklärt:

Von der CollectionSchnittstelle:

Wenn eine Sammlung addein bestimmtes Element aus einem anderen Grund als dem, dass sie das Element bereits enthält, ablehnt , muss sie eine Ausnahme auslösen (anstatt false zurückzugeben). Dadurch bleibt die Invariante erhalten, dass eine Sammlung nach der Rückkehr dieses Aufrufs immer das angegebene Element enthält.

Von der QueueSchnittstelle

Bei Verwendung von Warteschlangen, die Einfügungsbeschränkungen auferlegen können (z. B. Kapazitätsgrenzen), ist die Methode offerim Allgemeinen der Methode vorzuziehen Collection.add(E), bei der ein Element nur durch Auslösen einer Ausnahme nicht eingefügt werden kann.

PriorityQueueist eine QueueImplementierung, die keine Einfügungsbeschränkungen auferlegt. Deshalb addund offerhaben Methoden die gleiche Semantik.

Im Gegensatz dazu ArrayBlockingQueueist eine Implementierung , in der offerund addverhalten sich anders, je nachdem , wie die Warteschlange instanziiert wurde.


8

Der Unterschied ist folgender:

  • Angebotsmethode - versucht, ein Element zu einer Warteschlange hinzuzufügen, und gibt false zurück, wenn das Element nicht hinzugefügt werden kann (z. B. wenn eine Warteschlange voll ist), oder true, wenn das Element hinzugefügt wurde, und löst keine bestimmte Ausnahme aus .

  • Methode add - versucht, ein Element zu einer Warteschlange hinzuzufügen, gibt true zurück , wenn das Element hinzugefügt wurde, oder löst eine IllegalStateException aus, wenn derzeit kein Speicherplatz verfügbar ist.


1
Die Methode add gibt niemals false zurück, wenn das Element bereits verfügbar ist. Queue <String> q = new PriorityQueue <> (); String b = "Java"; Boolescher Wert is1 = q.add (b); boolean is2 = q.add ("java"); Boolescher Wert is3 = q.add (b); boolean is4 = q.offer ("java"); Boolescher Wert is5 = q.offer (b); Boolescher Wert is6 = q.offer (b); System.out.println ("qq ::" + q);
Raj

Danke, Raj! Ich habe meine Antwort oben aktualisiert. In der Oracle-Dokumentation heißt es: "Die Angebotsmethode fügt nach Möglichkeit ein Element ein, andernfalls wird false zurückgegeben. Dies unterscheidet sich von der Collection.add-Methode, bei der ein Element nur durch Auslösen einer nicht aktivierten Ausnahme nicht hinzugefügt werden kann. Die Angebotsmethode ist für die Verwendung bei einem Fehler vorgesehen ist eher ein normales als ein außergewöhnliches Ereignis, beispielsweise in Warteschlangen mit fester Kapazität (oder "begrenzten"). "
Maksym Ovsianikov

7

aus dem Quellcode in JDK 7 wie folgt:

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

Wir können leicht erkennen, dass die Funktion add true zurückgibt, wenn ein neues Element erfolgreich in die Warteschlange aufgenommen wurde. Wenn dies jedoch fehlschlägt, wird eine Ausnahme ausgelöst.


5

Die QueueSchnittstelle gibt an, dass add()ausgelöst wird, IllegalStateExceptionwenn derzeit kein Speicherplatz verfügbar ist (und andernfalls zurückgegeben wird true), während zurückgegeben offer()wird, falsewenn das Element aufgrund von Kapazitätsbeschränkungen nicht eingefügt werden konnte.

Der Grund, warum sie in a identisch sind, PriorityQueueist, dass diese Warteschlange als unbegrenzt angegeben ist, dh es gibt keine Kapazitätsbeschränkungen. Wenn keine Kapazitätsbeschränkungen bestehen, zeigen die Verträge von add()und offer()dasselbe Verhalten.


2

Ich werde den Beispielcode für den Java-Vertrag für die Angebotsmethode schreiben und eine Methode hinzufügen, die zeigt, wie sie sich unterscheiden.

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

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

Die Angebotsmethode fügt nach Möglichkeit ein Element ein, andernfalls wird false zurückgegeben. Dies unterscheidet sich von der Collection.add-Methode, bei der ein Element nur durch Auslösen einer nicht aktivierten Ausnahme nicht hinzugefügt werden kann. Die Angebotsmethode ist für die Verwendung konzipiert, wenn ein Fehler eher normal als außergewöhnlich ist, z. B. in Warteschlangen mit fester Kapazität (oder "begrenzt").

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.