Remplacer méthode equals
newbie question ici:
Donc, dans mon université devoirs que j'ai à remplacer la classe de l'objet est égale à la méthode pour une nouvelle classe créée par moi.
La nouvelle de la classe "Produit", chaque produit a un attribut "id" qui est unique. Donc, c'est comment je Surdéfini:
@Override
public boolean equals(Object obj) {
final Product other = (Product) obj;
if (id != other.id)
return false;
return true;
}
Le truc, c'est que cela est de 1,5 points sur 10 et il m'a fait suspicius être facile. J'ai donc commencé à chercher et j'ai trouvé des choses comme:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Product other = (Product) obj;
if (id != other.id)
return false;
return true;
}
Qui n'ont pas de sens pour moi, parce que je pense que le dernier vérifier si tous les autres fi des restrictions. Qu'avez-vous pensez?Qui est la meilleure façon de Remplacer cette méthode?
Merci!
Le contrat est égal, dit que tous les objets qui sont égaux doivent avoir le même code de hachage. Donc, si vous remplacez equals() il est nécessaire de redéfinir hashCode().
OriginalL'auteur Iñaki | 2011-06-15
Vous devez vous connecter pour publier un commentaire.
Le second morceau de code, c'est mieux:
x.equals(x)
, ce qui n'est pas nécessaire pour la correction, mais est utile pour l'optimisationx.equals(null)
au lieu de les jeterNullPointerException
ClassCastException
vôtre (par exemple,x.equals("foo")
)obj.equals(x)
pourrait appeler une méthode différente, donnant un résultat différent.Cela dépend de ce que tu veux dire par "travail". Il ne traitera pas une instance de Produit comme étant égal à une instance de la sous-classe, non - mais je ne pense pas que c'est cassé, c'est juste un comportement qui doit être documentée.
un.equals(b) renverra toujours false si une.getClass() == Product.class, b instanceof certains sous-classe de Produit, et a et b ont le même état interne. Ainsi, la equals() de la relation n'est pas fait symétrique. Cela est une violation de java.lang.Objet du contrat.
Il ne sera asymétrique si
b.equals(a)
retourne vrai... et il ne serait pas si c'appelésuper.equals(a)
qui il le devrait. Sans cette case,a.equals(b)
seulementid
pour qu'il puisse retourner true lors de lab.equals(a)
serait de retour faux commea
n'est pas une instance de la même sous-classe deProduct
ou une sous-classe de cette sous-classe. L'appel àgetClass()
est précisément là pour aide symétrie.Si on a une classe abstraite qui représente une immuable combinaison de valeurs (par exemple, une matrice 2d de
double
), mais n'a pas de mandat particulier d'un format de stockage, il peut être judicieux de définir l'égalité et le code de hachage en fonction de ces valeurs. Dans un tel cas, unIdentityMatrix with
" Taille égale à trois peut raisonnablement comparer égale à unDiagonalMatrix
avecDiagonalValues
holding {1.0,1.0,1.0}.OriginalL'auteur Jon Skeet
La deuxième version est sûre, je dirais futile. Votre version, au lieu de cela, pourrait lancer une
ClassCastException
parce que vous êtes en supposant que le moteur d'exécution type de la variableobj
est de type produit. Ce qui n'est pas vrai, c'est pourquoi vous devez utiliserthis.getClass() != obj.getClass()
(vous pourriez résoudre ce problème aussi avecinstanceof
opérateur).Si je ne
J'obtiens une exception alors que je devrais obtenir
false
.En outre, il gère les
product.equals(null)
problème, qui doit retourner false comme indiqué dansequals
contrat de méthode dans la documentation. Si vous ne vous inquiétez pas à ce sujet et vous n'avez, à l'intérieur de vous est égal à:instanceof
dans un non-finale de la classe donne une symétrie problème si la classe est sous-classé.Oui, vous avez raison. Je pensais sur la substitution de nouveau dans une sous-classe..
OriginalL'auteur Jack
La commune idiome utilisé en remplaçant equals() est
Dans la deuxième version que vous avez posté:
l'optimisation, seulement si les conditions suivantes
les contrôles sont beaucoup trop cher. Mais
ce n'est pas le cas, donc c'est juste
code redondant qui est mal.
ne change pas la sémantique de la méthode equals().
(Par exemple une classe qui
fournit une certaine méthode de convenance, mais
aucun autre état interne de l'
des objets.) C'est à cause de la
troisième si().
OriginalL'auteur ignis
Numéro 2 est à droite en sortant de Efficace Java de la façon la plus sûre pour remplacer égal à égal. 1 a un nullpointer si l'Objet est nulle et il n'est pas optimisé comme il pourrait être(ne pas vérifier si ojb est une référence à lui-même)
OriginalL'auteur nsfyn55
La solution proposée par "Joshua Bloch: Effective Java" est (en supposant que
Product
ne dispose pas d'une super-classe autre queObject
):Votre première solution présente deux inconvénients:
new Product(1).equals(null)
lève une exception NullpointerException bien qu'il est spécifié de fausse déclaration dans l'Objet.equals().new Product(1).equals(new Vector())
jette un ClassCastException bien qu'il est spécifié de fausse déclaration dans l'Objet.equals().Ces deux sont corrigées par l'instance de contrôle. Le
if (this == obj) return true;
est souvent utile pour l'efficacité, mais probablement pas nécessaire ici.La deuxième solution que vous avez posté le rend difficile à écrire une sous-classe de Produit avec de bonne sémantique. Si vous avez une sous-classe
vous aurez
!new Product(4).equals(new SubProduct(4))
. Cela est une violation de Liskov de susbstitution principe et qui est souvent cru être pas si bon. Si vous avez une classe finalela deuxième solutions est le même que ci-dessus.
SubProduct
a plus d'état et plus de remplacementsequals
- ensuite, si vous utilisezinstanceof
vous vous retrouvez aveca.equals(b) != b.equals(a)
, qui viole lesObject
contrat. Avec la même classe peuvent ne pas toujours être ce que vous voulez en termes de Liskov, mais t permettre la sous-classement sans casser laObject
contrat. L'égalité, le long d'une hiérarchie d'héritage est fondamentalement douloureux 🙁Entièrement d'accord. J'ai soigneusement évité de dire "faux". J'étais pas tellement attention à lire les autres réponses, cependant, et vous avez raté votre encore plus concise de contre exemples.
OriginalL'auteur Christoph Zenger