Lorsqu'une classe en Java ne remplace pas hashCode () , l'impression d'une instance de cette classe donne un joli numéro unique.
Le Javadoc de l'objet dit à propos de hashCode () :
Autant qu'il est raisonnablement pratique, la méthode hashCode définie par la classe Object renvoie des entiers distincts pour des objets distincts.
Mais lorsque la classe remplace hashCode () , comment puis-je obtenir son numéro unique?
Réponses:
System.identityHashCode (yourObject) donnera le code de hachage «original» de yourObject sous forme d'entier. L'unicité n'est pas nécessairement garantie. L'implémentation Sun JVM vous donnera une valeur qui est liée à l'adresse mémoire d'origine de cet objet, mais c'est un détail d'implémentation et vous ne devriez pas vous y fier.
EDIT: Réponse modifiée suite au commentaire de Tom ci-dessous re. adresses mémoire et objets en mouvement.
la source
System.identityHashCode()
?Le javadoc pour Object spécifie que
Si une classe remplace hashCode, cela signifie qu'elle veut générer un identifiant spécifique, qui (on peut l'espérer) aura le bon comportement.
Vous pouvez utiliser System.identityHashCode pour obtenir cet identifiant pour n'importe quelle classe.
la source
hashCode()
n'est pas pour fournir un identifiant unique pour un objet. Il résume plutôt l'état de l'objet (c'est-à-dire les valeurs des champs membres) en un seul entier. Cette valeur est principalement utilisée par certaines structures de données basées sur le hachage comme les cartes et les ensembles pour stocker et récupérer efficacement des objets.Si vous avez besoin d'un identifiant pour vos objets, je vous recommande d'ajouter votre propre méthode au lieu de remplacer
hashCode
. Pour cela, vous pouvez créer une interface de base (ou une classe abstraite) comme ci-dessous.Exemple d'utilisation:
la source
Peut-être que cette solution rapide et sale fonctionnera?
Cela donne également le nombre d'instances d'une classe en cours d'initialisation.
la source
System.identityHashCode
c'est une meilleure solutionAtomicLong
comme dans cette réponse .S'il s'agit d'une classe que vous pouvez modifier, vous pouvez déclarer une variable de classe
static java.util.concurrent.atomic.AtomicInteger nextInstanceId
. (Vous devrez lui donner une valeur initiale de la manière la plus évidente.) Ensuite, déclarez une variable d'instanceint instanceId = nextInstanceId.getAndIncrement()
.la source
J'ai trouvé cette solution qui fonctionne dans mon cas où j'ai des objets créés sur plusieurs threads et qui sont sérialisables:
la source
Si vous examinez les
hashcode
types Java lorsque vous effectuez une opération.toString()
sur un objet, le code sous-jacent est le suivant:la source
Juste pour augmenter les autres réponses sous un angle différent.
Si vous souhaitez réutiliser des codes de hachage à partir de «ci-dessus» et en dériver de nouveaux en utilisant l'état immuable de votre classe, alors un appel à super fonctionnera. Bien que cela puisse / ne puisse pas monter en cascade jusqu'à Object (c'est-à-dire qu'un ancêtre peut ne pas appeler super), cela vous permettra de dériver des codes de hachage par réutilisation.
la source
Il existe une différence entre les retours hashCode () et identityHashCode (). Il est possible que pour deux objets inégaux (testés avec ==) o1, o2 hashCode () puisse être le même. Voir l'exemple ci-dessous comment cela est vrai.
la source
J'ai eu le même problème et je n'ai été satisfait d'aucune des réponses jusqu'à présent, car aucune d'entre elles ne garantissait des identifiants uniques.
Moi aussi, je voulais imprimer les ID d'objet pour le débogage à dessein. Je savais qu'il devait y avoir un moyen de le faire, car dans le débogueur Eclipse, il spécifie des ID uniques pour chaque objet.
J'ai trouvé une solution basée sur le fait que l'opérateur "==" pour les objets ne retourne vrai que si les deux objets sont en fait la même instance.
Je pense que cela devrait garantir des identifiants uniques tout au long de la durée de vie du programme. Notez cependant que vous ne souhaiterez probablement pas l'utiliser dans une application de production car elle conserve des références à tous les objets pour lesquels vous générez des ID. Cela signifie que les objets pour lesquels vous créez un ID ne seront jamais récupérés.
Étant donné que j'utilise cela à des fins de débogage, je ne suis pas trop préoccupé par la mémoire libérée.
Vous pouvez modifier cela pour permettre d'effacer des objets ou de supprimer des objets individuels si la libération de mémoire est un problème.
la source