Supposons que je crée un objet et que je l'ajoute à mon ArrayList
. Si je crée ensuite un autre objet avec exactement la même entrée de constructeur, la contains()
méthode évaluera-t-elle que les deux objets sont identiques? Supposons que le constructeur ne fasse rien de drôle avec l'entrée et que les variables stockées dans les deux objets sont identiques.
ArrayList<Thing> basket = new ArrayList<Thing>();
Thing thing = new Thing(100);
basket.add(thing);
Thing another = new Thing(100);
basket.contains(another); // true or false?
class Thing {
public int value;
public Thing (int x) {
value = x;
}
equals (Thing x) {
if (x.value == value) return true;
return false;
}
}
Est-ce ainsi que le class
devrait être mis en œuvre pour avoir un contains()
retour true
?
java
object
arraylist
evaluation
Mantas Vidutis
la source
la source
Object
plutôt qu'unThing
. Sinon, votre méthode d'égalité ne sera pas utilisée. :)Collections
faire leur travail de manière optimisée, ce qui signifie quecontains()
vérifie d'abord lehashCode
s des deux objets, puis seulement appelleequals()
. Si leshashCode
s sont différents (ce qui est toujours le cas pour deux instances différentes deThing
), laequals()
méthode ne sera pas appelée. En règle générale, lorsque vous remplacezequals()
, vous ne devez pas oublier de remplacerhashCode()
également.Je pense que les bonnes implémentations devraient être
la source
if
n'est pas nécessaire.instanceof
est assez.object != null
condition n'est pas nécessaire, car elleobject instanceof Thing
vérifie que l'objet n'est pas également nul.L'ArrayList utilise la méthode equals implémentée dans la classe (votre classe Thing case) pour faire la comparaison des égaux.
la source
En règle générale, vous devez également remplacer
hashCode()
chaque fois que vous remplacezequals()
, même si ce n'est que pour l'amélioration des performances.HashCode()
décide dans quel «compartiment» votre objet est trié lors de la comparaison, de sorte que deux objetsequal()
évalués à true doivent renvoyer le mêmehashCode
value()
. Je ne me souviens pas du comportement par défaut dehashCode()
(s'il renvoie 0, alors votre code devrait fonctionner mais lentement, mais s'il renvoie l'adresse, votre code échouera). Je me souviens d'un tas de fois où mon code a échoué car j'ai oublié de remplacerhashCode()
. :)la source
Il utilise la méthode equals sur les objets. Donc, à moins que Thing ne remplace égal et utilise les variables stockées dans les objets à des fins de comparaison, il ne renverra pas true sur la
contains()
méthode.la source
Vous devez écrire:
Maintenant ça marche ;)
la source
Je voulais juste noter que l'implémentation suivante est incorrecte quand ce
value
n'est pas un type primitif:Dans ce cas, je propose ce qui suit:
la source
D'autres affiches ont abordé la question de savoir comment contient () fonctionne.
Un aspect tout aussi important de votre question est de savoir comment implémenter correctement equals (). Et la réponse à cela dépend vraiment de ce qui constitue l'égalité d'objet pour cette classe particulière. Dans l'exemple que vous avez fourni, si vous avez deux objets différents qui ont tous les deux x = 5, sont-ils égaux? Cela dépend vraiment de ce que vous essayez de faire.
Si vous n'êtes intéressé que par l'égalité des objets, l' implémentation par défaut de .equals () (celle fournie par Object) utilise uniquement l'identité (c'est-à-dire ceci == autre). Si c'est ce que vous voulez, alors n'implémentez pas equals () sur votre classe (laissez-la hériter d'Object). Le code que vous avez écrit, bien qu'il soit correct si vous optez pour l'identité, n'apparaîtrait jamais dans une vraie classe b / c, il n'offre aucun avantage par rapport à l'utilisation de l'implémentation Object.equals () par défaut.
Si vous débutez avec ce genre de choses, je recommande fortement le livre Effective Java de Joshua Bloch. C'est une excellente lecture et couvre ce genre de chose (plus comment implémenter correctement equals () lorsque vous essayez de faire plus que des comparaisons basées sur l'identité)
la source
Raccourci depuis JavaDoc :
booléen contient (Object o)
Renvoie true si cette liste contient l'élément spécifié. Plus formellement, retourne vrai si et seulement si cette liste contient au moins un élément e tel que (o == null? E == null: o.equals (e))
la source