2010-04-24 5 views
76

Prenez le PriorityQueue par exemple http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)Quelle est la différence entre les méthodes add et offer dans une file d'attente en Java?

Quelqu'un peut-il me donner un exemple d'un Queue où les méthodes add et offer sont différentes?

Selon le document Collection, la méthode add cherche souvent à s'assurer qu'un élément existe dans le Collection plutôt que d'ajouter des doublons. Ma question est la suivante: quelle est la différence entre les méthodes add et offer?

Est-ce que la méthode offer ajoutera des doublons malgré tout? (Je doute que ce soit parce que si un Collection ne devrait avoir que des éléments distincts ceci contournerait cela).

EDIT: Dans un PriorityQueue les méthodes add et offer sont la même méthode (voir ma réponse ci-dessous). Quelqu'un peut-il me donner un exemple d'une classe où les méthodes add et offer sont différentes?

Répondre

109

Je suppose que la différence est dans le contrat, que lorsque L'élément ne peut pas être ajouté à la collection. La méthode add lève une exception et offer non.

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

Si une collection refuse d'ajouter un élément particulier pour une raison quelconque autre que celle-ci contient déjà l'élément, il doit jeter une exception (plutôt que de retourner faux). Cela préserve l'invariant qu'une collection contient toujours l'élément renvoyé après cet appel .

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

Inserts l'élément spécifié dans cette file d'attente, si possible. Lors de l'utilisation files d'attente qui peuvent imposer l'insertion restrictions (par exemple la capacité limites), l'offre de la méthode est généralement préférable à la méthode Collection.add (E), qui peut ne pas insérer un élément uniquement en lançant une exception .

+0

+1 pour trouver cet extrait sur le moment d'utiliser 'offer' vs' add'. – Finbarr

19

Il n'y a pas de différence pour la mise en œuvre de PriorityQueue.add:

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

Pour AbstractQueue il est en fait une différence:

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

Je sais, je viens de poster cette réponse moi-même il y a quelques minutes. Connaissez-vous des classes où la méthode 'add' est différente de la méthode' offer'? – Finbarr

+0

@Finbarr: Oui, vérifiez ma réponse mise à jour –

10

La différence entre offer et add est expliqué par ces deux extraits des javadocs:

Depuis l'interface Collection:

Si une collection refuse de add un élément particulier pour toute autre raison que s'il contient déjà l'élément, il doit lancer une exception (plutôt que de retourner false). Cela préserve l'invariant qu'une collection contient toujours l'élément spécifié après le retour de cet appel.

partir de l'interface Queue

Lors de l'utilisation des files d'attente qui peuvent imposer des restrictions d'insertion (pour les limites de capacité, par exemple), la méthode offer est généralement préférable à la méthode Collection.add(E), qui peut ne pas insérer un seul élément en jetant une exception.

PriorityQueue est une implémentation Queue qui n'impose aucune restriction d'insertion. Par conséquent, les méthodes add et offer ont la même sémantique.

En revanche, ArrayBlockingQueue est une implémentation dans laquelle offer etse comportent différemment, selon la façon dont la file d'attente a été instanciée.

0

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

La méthode offre insère un élément si possible, sinon faux retour. Cela diffère de la méthode Collection.add, qui peut échouer à ajouter un élément uniquement en lançant une exception non contrôlée. La méthode de l'offre est conçue pour être utilisée lorsque la défaillance est une occurrence normale plutôt qu'exceptionnelle, par exemple, dans des files d'attente à capacité fixe (ou "délimitée").

6

à partir du code source dans jdk 7 comme suit:

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

on peut facilement savoir que la fonction add retourne vrai quand ajouter avec succès un nouvel élément dans la file d'attente, mais lancer une exception lors d'un échec.

4

L'interface Queue précise que add() jetteront un IllegalStateException si aucun espace est actuellement disponible (et par ailleurs revenir true) tandis que offer() retournera false si l'élément n'a pas pu être inséré en raison des restrictions de capacité.

La raison pour laquelle ils sont identiques dans un PriorityQueue est que cette file d'attente est spécifiée pour être illimitée, c'est-à-dire qu'il n'y a pas de restrictions de capacité. En l'absence de restrictions de capacité, les contrats add() et offer() affichent le même comportement.

0

Je vais écrire le code d'exemple de contrat java pour la méthode d'offre et ajouter une méthode montrant comment ils diffèrent.

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 différence suit:

  • offre méthode - tente d'ajouter un élément à une file d'attente, et retourne faux si l'élément ne peut pas être ajouté (comme dans le cas où une file d'attente est pleine), ou true si l'élément a été ajouté et ne déclenche aucune exception spécifique.

  • ajouter la méthode - essaie d'ajouter un élément à une file d'attente, et retourne faux si l'élément est déjà présent dans la file d'attente, ou retourne vrai si l'élément a été ajouté, et il lance une exception si la file d'attente est pleine.

Questions connexes