En regardant le javadoc j'ai vu le fait qu'un ArrayList a une méthode add surchargée:
public boolean add (E e)
Ajoute l'élément spécifié à la fin de cette liste.
et
public void add (int index, élément E)
Insère l'élément spécifié à la position spécifiée dans cette liste. Déplace l'élément actuellement à cette position (le cas échéant) et tous les éléments suivants vers la droite (en ajoute un à leurs index).
J'ai remarqué que le premier retournait une boolean
tandis que le second était une void
. Il s'avère que la première add
DOIT retourner une boolean
parce que:
Renvoie: true (comme spécifié par Collection.add (E))
Je suis donc allé dans Collection.add (E) :
booléen ajouter (E e)
Garantit que cette collection contient l'élément spécifié (opération facultative). Renvoie true si cette collection a été modifiée à la suite de l'appel. (Retourne false si cette collection n'autorise pas les doublons et contient déjà l'élément spécifié.)
Ma question est donc la suivante: pourquoi add
est-il spécifié pour retourner un booléen au lieu d’être vide? Lorsque je add
quelque chose, je m'attendrais à ne faire qu'une opération.
Je comprends qu'il existe d'autres structures de données qui, contrairement à ArrayList, n'autorisent pas les doublons (tels que les ensembles). Mais même dans ce cas, le problème ne pourrait-il pas être résolu comme suit:
public void add(E e){
if(e is not in set){
add e;
}
}
Ainsi, si e
IS dans le jeu, aucune action n'est entreprise. Pourquoi est-il préférable de renvoyer une approche boolean
au lieu de l'approche void
?
Collection.add
est une méthode assez générique (pas au sens des génériques Java - dans le sens où elle est largement applicable). En tant que tels, ils voulaient une valeur de retour qui s’applique de manière générale.
Certaines classes (comme ArrayList
) acceptent toujours les éléments et retournent donc toujours true
. Vous avez raison de dire que dans ces cas, un type de retour void
serait tout aussi bon.
Mais d'autres, comme Set
, ne permettront parfois pas d'ajouter un élément. Dans le cas de Set
, cela se produit si un élément égal était déjà présent. C'est souvent utile de le savoir. Un autre exemple est une collection limitée (qui ne peut contenir qu'un certain nombre d'éléments).
Vous pouvez demander, "le code ne peut pas simplement vérifier ceci manuellement?" Par exemple, avec un ensemble:
if (!set.contains(item)) {
set.add(item);
itemWasAdded(item);
}
C'est plus verbeux que ce que vous pouvez faire maintenant, mais pas beaucoup:
if (set.add(item)) {
itemWasAdded(item);
}
Mais ce comportement check-then-act n'est pas thread-safe, ce qui peut être crucial dans les applications multithread. Par exemple, il se peut qu'un autre thread ait ajouté un élément égal entre vous vérifiant set.contains(item)
et set.add(item)
dans le premier extrait de code. Dans un scénario multithread, ces deux actions doivent vraiment être une seule action atomique; renvoyer boolean
de la méthode rend cela possible.
car il est souvent utile de savoir si quelque chose a été ajouté ou s’il était déjà présent.
Parce que c'est une information supplémentaire qui ne coûte rien et qui peut être utile dans certaines situations. Par exemple:
Set<String> set = new HashSet<String>();
set.add("foobar");
boolean wasAlreadyThere = set.add("foobar");
Sinon, il faudrait faire
boolean wasAlreadyThere = set.contains("foobar");
set.add("foobar");
ce qui nécessite deux fois plus de travail (vous devez d'abord rechercher, puis rechercher à nouveau pour ajouter).