Quelle est la différence entre les méthodes d'ajout et d'offre dans une file d'attente en Java?

109

Prenons l' PriorityQueueexemple http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Quelqu'un peut-il me donner un exemple Queueoù le addetoffer méthodes sont différentes?

Selon le Collectiondocument, la addméthode cherchera souvent à s'assurer qu'un élément existe dans le Collectionplutôt qu'à ajouter des doublons. Ma question est donc la suivante: quelle est la différence entre les méthodes addet offer?

Est-ce que la offerméthode ajoutera des doublons malgré tout? (Je doute que ce soit parce que si un Collectionne devait avoir que des éléments distincts, cela éviterait cela).

EDIT: Dans un PriorityQueueles méthodes addet offersont la même méthode (voir ma réponse ci-dessous). Quelqu'un peut-il me donner un exemple de classe où les méthodes addet offersont différentes?

Finbarr
la source

Réponses:

148

Je suppose que la différence réside dans le contrat, que lorsque l'élément ne peut pas être ajouté à la collection, la addméthode lève une exception et offerne le fait pas.

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 autre que le fait qu'elle contient déjà l'élément, elle doit lever une exception (plutôt que de renvoyer false). Cela préserve l'invariant qu'une collection contient toujours l'élément spécifié après le retour de cet appel.

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

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

DVD
la source
4
+1 pour conclure que snippet quand utiliser offervs add.
Finbarr
28

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

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

Car AbstractQueueil y a en fait une différence:

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");
}
Peter Lang
la source
Je sais, je viens de publier cette réponse moi-même il y a quelques minutes. Connaissez-vous des classes où la addméthode est différente de la offerméthode?
Finbarr
13

La différence entre offeret addest expliquée par ces deux extraits des javadocs:

Depuis l' Collectioninterface:

Si une collection refuse addun élément particulier pour une raison autre que le fait qu'elle contient déjà l'élément, elle doit lever une exception (plutôt que de renvoyer false). Cela préserve l'invariant qu'une collection contient toujours l'élément spécifié après le retour de cet appel.

Depuis l' Queueinterface

Lors de l'utilisation de files d'attente pouvant imposer des restrictions d'insertion (par exemple des limites de capacité), la méthode offerest généralement préférable à la méthode Collection.add(E), qui peut échouer à insérer un élément uniquement en lançant une exception.

PriorityQueueest une Queueimplémentation qui n'impose aucune restriction d'insertion. Par conséquent, les méthodes addet offeront la même sémantique.

En revanche, ArrayBlockingQueueest une implémentation dans laquelle offeret addse comporte différemment, selon la façon dont la file d'attente a été instanciée.

Stephen C
la source
8

La différence est la suivante:

  • offer method - essaie d'ajouter un élément à une file d'attente, et retourne false 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 lève aucune exception spécifique .

  • add method - essaie d'ajouter un élément à une file d'attente, retourne true si l'élément a été ajouté ou lève une IllegalStateException si aucun espace n'est actuellement disponible.

Maksym Ovsianikov
la source
1
La méthode add ne retourne jamais false si l'élément est déjà disponible Queue <String> q = new PriorityQueue <> (); Chaîne b = "java"; booléen is1 = q.add (b); booléen is2 = q.add ("java"); booléen is3 = q.add (b); booléen is4 = q.offer ("java"); booléen is5 = q.offer (b); booléen is6 = q.offer (b); System.out.println ("qq ::" + q);
Raj
Merci, Raj! J'ai mis à jour ma réponse ci-dessus. La documentation Oracle indique: "La méthode offer insère un élément si possible, sinon renvoie false. Cela diffère de la méthode Collection.add, qui peut échouer à ajouter un élément uniquement en lançant une exception non cochée. La méthode offer est conçue pour être utilisée en cas d'échec est une occurrence normale, plutôt qu'exceptionnelle, par exemple, dans les files d'attente à capacité fixe (ou «limitées»). »
Maksym Ovsianikov
7

à 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");
}

nous pouvons facilement savoir que la fonction add renverra true lors de l'ajout réussi d'un nouvel élément dans la file d'attente, mais lèvera une exception en cas d'échec.

Heavin
la source
5

L' Queueinterface spécifie qui add()lancera un IllegalStateExceptionsi aucun espace n'est actuellement disponible (et sinon retournera true) tandis que offer()retournera falsesi l'élément n'a pas pu être inséré en raison de restrictions de capacité.

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

Peter
la source
2

J'écrirai l'exemple de code de contrat java pour la méthode d'offre et j'ajouterai une méthode montrant en quoi 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
Anwer Aslam
la source
0

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

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

Yeshodhan Kulkarni
la source