Cas d’utilisation pour IdentityHashMap

Quelqu’un pourrait-il s’il vous plaît dire quels sont les cas d’utilisation importants de IdentityHashMap ?

Les documentations disent:

Une utilisation typique de cette classe est la transformation de graphes d’object préservant la topologie, telle que la sérialisation ou la copie profonde. Pour effectuer une telle transformation, un programme doit conserver une “table de noeuds” qui assure le suivi de toutes les références d’objects déjà traitées. La table de nœuds ne doit pas assimiler des objects distincts même s’ils sont égaux. Une autre utilisation typique de cette classe est la gestion des objects proxy. Par exemple, une installation de débogage peut souhaiter conserver un object proxy pour chaque object du programme en cours de débogage.

Chaque fois que vous voulez que vos clés ne soient pas comparées par des equals mais par == vous utiliserez une IdentityHashMap. Cela peut être très utile si vous manipulez beaucoup de références, mais uniquement dans des cas très particuliers.

Un cas où vous pouvez utiliser IdentityHashMap est si vos clés sont des objects de classe. C’est environ 33% plus rapide que HashMap pour obtenir! Il utilise probablement moins de mémoire aussi.

HashMap crée des objects Entrée chaque fois que vous ajoutez un object, ce qui peut être très stressant lorsque vous avez beaucoup d’objects. Dans un HashMap avec 1 000 objects ou plus, vous finirez par utiliser une bonne partie de votre CPU en ayant simplement les entrées de nettoyage du GC (dans des situations telles que le pathfinding ou d’autres collections uniques créées puis nettoyées). IdentityHashMap n’a pas ce problème, donc finira par être beaucoup plus rapide.

Voir un benchmark ici: http://www.javagaming.org/index.php/topic,21395.0/topicseen.html

Vous pouvez également utiliser IdentityHashMap comme carte à usage général si vous pouvez vous assurer que les objects que vous utilisez comme clés seront égaux si et seulement si leurs références sont égales.

À quel gain? Évidemment, cela sera plus rapide et utilisera moins de mémoire que des implémentations comme HashMap ou TreeMap .


En fait, il y a beaucoup de cas où cela se produit. Par exemple:

  • Enum s. Bien que pour les énumérations, il existe même une meilleure alternative: EnumMap
  • Objets de Class . Ils sont également comparables par référence.
  • Interned Ssortingng s. Soit en les spécifiant comme littéraux, soit en appelant Ssortingng.intern() sur eux.
  • Instances en cache. Certaines classes fournissent la mise en cache de leurs instances. Par exemple en citant le javadoc d’ Integer.valueOf(int) :

Cette méthode mettra toujours en cache les valeurs comsockets entre -128 et 127, inclusivement …

  • Certaines bibliothèques / frameworks gèrent exactement une instance de types ceratin, par exemple Spring beans.
  • Types singleton. Si vous utilisez des istances de types construites avec le modèle Singleton , vous pouvez également être sûr que (au maximum) une instance existe et que le test d’égalité de référence est donc qualifié pour le test d’égalité.
  • Tout autre type dans lequel vous prenez explicitement en charge les mêmes références pour accéder aux valeurs utilisées pour placer des valeurs dans la carte.

  • Pour démontrer le dernier point:

     Map m = new IdentityHashMap<>(); // Any keys, we keep their references Object[] keys = { "strkey", new Object(), new Integer(1234567) }; for (int i = 0; i < keys.length; i++) m.put(keys[i], "Key #" + i); // We query values from map by the same references: for (Object key : keys) System.out.println(key + ": " + m.get(key)); 

    La sortie sera, comme prévu (car nous avons utilisé les mêmes références d' Object pour interroger les valeurs de la carte):

     strkey: Key #0 java.lang.Object@1c29bfd: Key #1 1234567: Key #2 

    Ceci est une expérience pratique de moi:

    IdentityHashMap laisse une empreinte mémoire beaucoup plus petite que HashMap pour les grandes cardinalités.

    Un cas important est celui où vous traitez des types de référence (par opposition aux valeurs) et vous voulez vraiment le bon résultat. Les objects malveillants peuvent avoir remplacé le hashCode et equals méthodes se prêtant à toutes sortes de méfaits. Malheureusement, il n’est pas utilisé aussi souvent qu’il devrait l’être. Si les types d’interface auxquels vous faites face ne remplacent pas hashCode et sont equals , vous devriez généralement opter pour IdentityHashMap .