Des inconvénients à utiliser des objets arbitraires comme clés de carte en Java?

StackOverflow https://stackoverflow.com/questions/635014

  •  10-07-2019
  •  | 
  •  

Question

J'ai dans l'application deux types d'objets, chaque objet d'un type ayant exactement un objet de l'autre type correspondant.

Le choix évident de suivre cette relation est un Map<type1, type2>, comme un HashMap. Mais de toute façon, je suis méfiant. Puis-je utiliser un objet comme clé dans la carte, le faire circuler, le placer dans une autre collection et extraire son partenaire de la carte à tout moment?

Après la création d'un objet, tout ce que je transmets est un identifiant, n'est-ce pas? Donc probablement pas de problème là-bas. Et si je sérialise et désérialise la clé?

D'autres mises en garde? Devrais-je utiliser quelque chose d'autre pour corréler les paires d'objets, comme un nombre que je génère moi-même?

Était-ce utile?

La solution

  1. La clé doit implémenter .equals() et .hashCode() correctement
  2. La clé ne doit pas être modifiée de quelque manière que ce soit qui modifie sa valeur HashMap alors qu'elle est utilisée comme clé
  3. Idéalement, tout objet utilisé comme clé dans un <=> devrait être immuable. Cela garantirait automatiquement que 2. est toujours considéré comme vrai.
  4. Les objets qui pourraient autrement être convertis en GCed peuvent être conservés lorsqu'ils sont utilisés comme clé et / ou valeur.

Autres conseils

  

J'ai deux types d'objets dans mon   application où chaque objet d'un   genre a exactement un correspondant   objet de l'autre genre.

Cela ressemble vraiment à une relation has-a et pourrait donc être implémenté en utilisant un attribut simple.

Cela dépend de la mise en oeuvre de la carte que vous choisissez:

  • HashMap utilise equals () et hashCode () . Par défaut (dans Object), ceux-ci sont basés sur l'identité de l'objet, ce qui fonctionnera correctement à moins que vous ne sérialisiez / désérialisiez. Avec une implémentation appropriée d’equals () et hashCode () en fonction du contenu de l’objet, vous n’aurez aucun problème, tant que vous ne le modifiez pas alors que c’est une clé dans une carte de hachage.

  • TreeMap utilise compareTo () . Il n'y a pas d'implémentation par défaut, vous devez donc en fournir une. Les mêmes limitations que pour l'implémentation de hashCode () et d'equals () ci-dessus s'appliquent.

Vous pouvez utiliser une carte standard, mais vous garderez ainsi des références fortes à vos objets dans la carte. Si vos objets sont référencés dans une autre structure et que vous avez besoin de la carte pour les relier, envisagez d'utiliser un WeakHashMap.

Et BTW, vous n’avez pas besoin de redéfinir equals et hashCode sauf si vous devez considérer plusieurs instances d’un objet comme égales ...

  

Puis-je utiliser un objet comme clé dans la carte, le faire circuler, le placer dans une autre collection et extraire son partenaire de la carte à tout moment?

Oui, pas de problème ici.

  

Après la création d'un objet, tout ce que je transmets est un identifiant, n'est-ce pas? Donc probablement pas de problème là-bas. Et si je sérialise et désérialise la clé?

C'est vrai, vous ne faites que passer d'une référence - ils vont tous pointer vers le même objet. Si vous sérialisez ou désérialisez l'objet, cela créerait un nouvel objet. Cependant, si votre objet implémente correctement equals et hashCode, vous devriez toujours pouvoir utiliser le nouvel objet désérialisé pour récupérer des éléments de la carte.

  

D'autres mises en garde? Devrais-je utiliser quelque chose d'autre pour corréler les paires d'objets, comme un nombre que je génère moi-même?

En ce qui concerne les mises en garde, vous ne pouvez rien modifier qui puisse modifier le hashCode de l'objet tant qu'il se trouve sur la carte.

Tout objet peut être une clé de carte. La chose importante à faire ici est de vous assurer que vous substituez les .equals () et .hashCode () à tous les objets qui seront utilisés comme clés de carte.

La raison pour laquelle vous faites cela est que si vous ne le faites pas, l'égalité sera comprise comme une égalité d'objet, et le seul moyen de trouver & "égal à &"; Les touches de la carte sont d'avoir un handle sur l'objet d'origine lui-même.

Vous écrasez hashcode car il doit être cohérent avec equals. C’est pour que les objets que vous avez définis comme étant égaux soient également identiques.

Les points d'échec sont les fonctions hashcode et equals. S'ils ne produisent pas de valeurs de retour cohérentes et correctes, la carte se comportera étrangement. Effective Java contient une section entière et est vivement recommandé.

Vous pourriez envisager de de Google Collection. BiMap .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top