suis-je correct en supposant que si vous avez un objet contenu dans un ensemble Java <> (ou en tant que clé dans une carte <> pour cette matière), tous les champs utilisés pour déterminer l'identité ou la relation (via (En d'autres termes, ces champs doivent être immuables, ou si vous devez retirer l'objet de la collection, puis modifié, puis réinséré.) p>
La raison pour laquelle je demande est que je lisais le Hibernate Annotations Guide de référence et il a un exemple où il existe un hashcode () code>,
est égal () code>,
comparète () code> etc.) ne peut pas être modifié sans causer un comportement non spécifié pour les opérations sur la collection? (Edit: Comme mentionné dans Cette autre question ) p>
hashset
jouet code> classes a champs
nom code> et
série code> qui sont mutables et sont également utilisés dans le
hashcode () code> Calcul ... Un drapeau rouge s'est éteint dans ma tête et je voulais juste m'assurer que j'ai compris les implications de celui-ci. p>
4 Réponses :
C'est correct, cela peut entraîner des problèmes de localisation de l'entrée de la carte. Officiellement, le comportement est indéfini, donc si vous l'ajoutez à un hashset ou en tant que clé dans un hashmap, vous ne devez pas le changer. P>
Oui, cela entraînera des choses graves.
// Given that the Toy class has a mutable field called 'name' which is used // in equals() and hashCode(): Set<Toy> toys = new HashSet<Toy>(); Toy toy = new Toy("Fire engine", ToyType.WHEELED_VEHICLE, Color.RED); toys.add(toy); System.out.println(toys.contains(toy)); // true toy.setName("Fast truck"); System.out.println(toys.contains(toy)); // false
Attendez, je viens de réaliser que c'était un exemple vraiment mauvais. Puisque j'ai toujours eu la référence de la référence, la dernière contient () retournera en fait vrai. Les hachemaps sont une question différente, mais cela quitte presque l'heure sur un week-end de trois jours et je ne veux pas creuser un exemple.
heh, postez quelque chose quand vous revenez - j'attends-le avec impatience.
Attendez de nouveau, j'ai oublié que Hashset utilise un haschmap comme support. Cela pourrait bien se produire: le hachemap de support utilise le hashcode pour sauter sur un seau avant de vérifier l'équivalent () sur les éléments du seau et la modification d'un élément le fera de sauter au mauvais godet et de ne pas trouver aucun élément là-bas.
Le javadoc pour Note: Les grands soins doivent être exercés si
Les objets mutables sont utilisés comme défini
éléments. Le comportement d'un ensemble n'est pas
spécifié si la valeur d'un objet est
changé d'une manière qui affecte
égale les comparaisons tandis que l'objet est
un élément dans l'ensemble. Un cas particulier
de cette interdiction est que ce n'est pas
Permissible pour un ensemble de contenir
elle-même comme un élément. p>
blockQuote>
Cela signifie simplement que vous pouvez utiliser des objets mutables dans un ensemble et même les changer. Il suffit de vous assurer que le changement n'a pas d'impact sur la manière dont le fichier définir code> dit p>
code> trouve les éléments. Pour
hashset code>, cela nécessiterait de ne pas modifier les champs utilisés pour calculer
hashcode () code>. P>
dans un hashset / hashmap, vous em> pourrait em> Mutater un objet contenu pour modifier les résultats de Vous pouvez également transformer des objets qui sont à l'intérieur d'une identitéHashmap - rien d'autre que l'identité d'objet sert à localiser le contenu. p>
Même si vous pouvez faire ces choses avec ces qualifications, elles rendent votre code plus fragile. Et si quelqu'un veut changer d'arbres plus tard, ou ajoutez ce champ mutable au test HashCode / Équilibre? P> comparète () code> Opération - La comparaison relative n'est pas utilisée pour localiser les objets. Mais ce serait fatal à l'intérieur d'un arbre / preemap. p>