Nehmen Sie zum Beispiel das PriorityQueue
http://Java.Sun.com/j2se/1.5.0/docs/api/Java/util/PriorityQueue.html#offer ( E)
Kann mir jemand ein Beispiel für ein Queue
geben, bei dem das add
und offer
Methoden sind unterschiedlich?
Gemäß dem Collection
doc versucht die add
-Methode häufig sicherzustellen, dass ein Element in der vorhanden ist Collection
anstatt Duplikate hinzuzufügen. Meine Frage ist also, was ist der Unterschied zwischen den Methoden add
und offer
?
Ist es so, dass die offer
-Methode Duplikate hinzufügt? (Ich bezweifle, dass es daran liegt, dass wenn ein Collection
nur unterschiedliche Elemente haben sollte, dies dies umgehen würde).
BEARBEITEN: In einem PriorityQueue
sind die add
und offer
Methoden die gleiche Methode (siehe meine Antwort unten). Kann mir jemand ein Beispiel für eine Klasse geben, in der die Methoden add
und offer
unterschiedlich sind?
Ich vermute, der Unterschied liegt im Vertrag, dass die add
-Methode eine Ausnahme auslöst, wenn ein Element nicht zur Sammlung hinzugefügt werden kann, und offer
dies 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 bereits ein Element 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 Auflistung nach der Rückgabe 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, falls möglich, in diese Warteschlange ein. Bei der Verwendung von Warteschlangen, die Einfügungseinschränkungen auferlegen können (z. B. Kapazitätsgrenzen), ist das Methodenangebot im Allgemeinen der Methode Collection.add (E) vorzuziehen, bei der das Einfügen eines Elements nur durch Auslösen einer Ausnahme fehlschlagen kann.
Es gibt keinen Unterschied für die Implementierung von PriorityQueue.add
:
public boolean add(E e) {
return offer(e);
}
Für AbstractQueue
gibt es tatsächlich einen Unterschied:
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
Der Unterschied zwischen offer
und add
wird durch diese beiden Auszüge aus den Javadocs erklärt:
Von der Collection
Schnittstelle:
Wenn eine Auflistung es ablehnt, ein bestimmtes Element aus einem anderen Grund als dem, der bereits das Element enthält, zu
add
, muss sie eine Ausnahme auslösen (anstatt false zurückzugeben). Dadurch bleibt die Invariante erhalten, dass eine Auflistung nach der Rückgabe dieses Aufrufs immer das angegebene Element enthält.
Von der Queue
Schnittstelle
Bei der Verwendung von Warteschlangen, die Einfügungseinschränkungen auferlegen können (z. B. Kapazitätsgrenzen), ist die Methode
offer
im Allgemeinen der MethodeCollection.add(E)
vorzuziehen, bei der das Einfügen eines Elements nur durch Auslösen einer Ausnahme fehlschlagen kann.
PriorityQueue
ist eine Queue
Implementierung, die keine Einfügebeschränkungen auferlegt. Daher haben die Methoden add
und offer
dieselbe Semantik.
Im Gegensatz dazu ist ArrayBlockingQueue
eine Implementierung, in der sich offer
und add
unterschiedlich verhalten, je nachdem, wie die Warteschlange instanziiert wurde.
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 Add-Funktion true zurückgibt, wenn ein neues Element erfolgreich in die Warteschlange eingefügt wurde, aber eine Ausnahme auslöst, wenn dies fehlschlägt.
Der Unterschied ist folgender:
offer Methode - versucht, ein Element zu einer Warteschlange hinzuzufügen und gibt false wenn das Element kann nicht hinzugefügt werden (wie in dem Fall, wenn eine Warteschlange voll ist) oder true wenn das Element hinzugefügt wurde, und wirft keine bestimmte Ausnahme.
add Methode - versucht, ein Element zu einer Warteschlange hinzuzufügen, gibt true zurück, wenn das Element vorhanden war hinzugefügt oder löst eine IllegalStateException aus, wenn derzeit kein Speicherplatz verfügbar ist.
Die Schnittstelle Queue
gibt an, dass add()
ein IllegalStateException
auslöst, wenn derzeit kein Speicherplatz verfügbar ist (und andernfalls true
zurückgibt), während offer()
gibt false
zurück, wenn das Element aufgrund von Kapazitätsbeschränkungen nicht eingefügt werden konnte.
Der Grund, warum sie in PriorityQueue
gleich sind, ist, dass diese Warteschlange als nicht begrenzt angegeben ist, d. H. Es gibt keine Kapazitätsbeschränkungen. Wenn keine Kapazitätsbeschränkungen vorliegen, zeigen die Verträge von add()
und offer()
dasselbe Verhalten.
Ich werde den Java Vertragsbeispielcode 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
Quelle: http://docs.Oracle.com/javase/6/docs/api/Java/util/Queue.html
Die offer-Methode fügt nach Möglichkeit ein Element ein, andernfalls wird false zurückgegeben. Dies unterscheidet sich von der Collection.add-Methode, bei der das Hinzufügen eines Elements nur durch Auslösen einer nicht aktivierten Ausnahme fehlschlagen kann. Die Angebotsmethode wurde für den Fall entwickelt, dass ein Fehler eher normal als außergewöhnlich auftritt, z. B. in Warteschlangen mit fester Kapazität (oder "beschränkt").