141 votes

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

Prenez par exemple la PriorityQueue sur http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Est-ce que quelqu'un peut me donner un exemple d'une Queue où les méthodes add et offer sont différentes?

Selon la documentation de la Collection, la méthode add cherchera souvent à s'assurer qu'un élément existe dans la Collection plutôt que d'ajouter des doublons. Alors ma question est, quelle est la différence entre les méthodes add et offer?

Est-ce que la méthode offer ajoutera des doublons quoi qu'il en soit? (Je doute que ce soit le cas car si une Collection ne devrait contenir que des éléments distincts, cela contournerait cette règle).

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

189voto

dvd Points 469

Je suppose que la différence se trouve dans le contrat, que lorsque l'élément ne peut pas être ajouté à la collection, la méthode add lance une exception et offer ne 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 en particulier pour une raison autre que le fait qu'elle contient déjà l'élément, elle doit déclencher une exception (plutôt que de renvoyer false). Cela préserve l'invariant selon lequel 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 qui peuvent imposer des restrictions d'insertion (par exemple des limites de capacité), la méthode offer 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.

7 votes

+1 pour avoir trouvé cet extrait sur quand utiliser offer par rapport à add.

38voto

Peter Lang Points 25877

La réponse courte : cela dépend de l'implémentation concrète.

Si votre file d'attente a une limite de capacité maximale, il y a effectivement une différence.

  • Cas n°1 (pas de limite de capacité maximale) appliquée :

Il n'y a pas de différence comme l'implémentation de PriorityQueue :

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

  • Cas n°2 (limite de capacité maximale) appliquée :

Il y a effectivement une différence comme l'implémentation de ArrayBlockingQueue qui étend AbstractQueue :

// ArrayBlockingQueue qui étend AbstractQueue
public boolean add(E e) {
    return super.add(e);
}

// AbstractQueue
public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("File pleine");
}
  • offer : si la file est pleine, renvoie false et ne lancera pas d'exception
  • add : si la file est pleine, lance une exception

0 votes

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 ?

20voto

Stephen C Points 255558

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

De l'interface Collection :

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 renvoyer une exception (plutôt que de renvoyer false). Cela préserve l'invariant selon lequel une collection contient toujours l'élément spécifié après que cet appel retourne.

De l'interface Queue

Lors de l'utilisation de files d'attente qui peuvent imposer des restrictions d'insertion (par exemple des limites de capacité), la méthode offer 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.

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

Par contre, ArrayBlockingQueue est une implémentation dans laquelle offer et add se comportent différemment, en fonction de la manière dont la file d'attente a été instanciée.

11voto

Peter Points 4694

L'interface Queue spécifie que add() lancera une IllegalStateException si aucun espace n'est actuellement disponible (sinon retournera true) tandis que offer() renverra false si l'élément n'a pas pu être inséré en raison de restrictions de capacité.

La raison pour laquelle elles sont les mêmes dans une PriorityQueue est que cette file est spécifiée comme illimitée, c'est-à-dire qu'il n'y a pas de restrictions de capacité. Dans le cas de l'absence de restrictions de capacité, les contrats de add() et offer() affichent le même comportement.

8voto

Heavin Points 1

À partir du code source dans jdk 7 comme suit :

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("File d'attente pleine");
}

Nous pouvons facilement savoir que la fonction add retournera vrai lorsqu'un nouvel élément est ajouté avec succès dans la file d'attente, mais lèvera une exception en cas d'échec.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X