web-dev-qa-db-fra.com

Pourquoi est-il utile d’avoir des valeurs NULL ou des clés NULL dans les cartes de hachage?

Hashtable n'autorise pas les clés ni les valeurs nulles, tandis que HashMap autorise les valeurs nulles et 1 clé nulle. 

Des questions:

  1. Pourquoi cela est-il ainsi? 
  2. Comment est-il utile d’avoir une telle clé et de telles valeurs dans HashMap?
23
sab

1. Pourquoi est-ce ainsi?

HashMap est plus récent que Hashtable et corrige certaines de ses limitations.

Je ne peux que deviner ce que les concepteurs pensaient, mais voici mes hypothèses:

  • Hashtable calcule un hachage pour chaque clé en appelant hashCode sur chaque clé. Cela échouerait si la clé était nulle, ce qui peut être une raison pour interdire les valeurs nulles en tant que clés. 
  • La méthode Hashtable.get renvoie la valeur null si la clé n'est pas présente. Si null était une valeur valide, il serait ambigu de savoir si null signifiait que la clé était présente mais qu'elle avait la valeur null, ou si la clé était absente. L'ambiguïté est mauvaise, cela pourrait donc être une raison pour interdire les valeurs nulles en tant que valeurs.

Cependant, il arrive parfois que vous souhaitiez réellement stocker des valeurs NULL. Les restrictions ont donc été supprimées dans HashMap. L'avertissement suivant était également inclus dans la documentation de HashMap.get :

Une valeur de retour de null n'indique pas nécessairement que la carte ne contient aucune correspondance pour la clé; il est également possible que la carte mappe explicitement la clé sur null.


2. Comment est-il utile d’avoir une telle clé et de telles valeurs dans HashMap?

Il est utile de stocker explicitement null pour faire la distinction entre une clé que vous know existez mais n’a pas de valeur associée et une clé qui n’existe pas. Un exemple est une liste d'utilisateurs enregistrés et leurs anniversaires. Si vous demandez la date de naissance d'un utilisateur spécifique, vous voulez pouvoir faire la distinction entre cet utilisateur qui n'existe pas et l'utilisateur existant, mais ils n'ont pas entré leur date de naissance.

Je ne vois aucune (bonne) raison de vouloir stocker null en tant que clé, et en général, je vous déconseille d'utiliser une clé null, mais il est probable qu'il y a au moins une personne quelque part qui a besoin de clés qui peuvent être nul.

38
Mark Byers

Eh bien, je pense que Mark Byers a répondu parfaitement, c’est donc un exemple simple dans lequel les valeurs nulles et les clés peuvent être utiles:

Imaginez que vous ayez une fonction coûteuse qui retourne toujours le même résultat pour la même entrée. Une carte est un moyen simple de mettre en cache ses résultats. Peut-être que parfois la fonction retournera null, mais vous devez quand même la sauvegarder, car l'exécution est coûteuse. Donc, les valeurs nulles doivent être stockées. La même chose s'applique à la clé nulle s'il s'agit d'une entrée acceptée pour la fonction.

11
sinuhepop

HashTable est une très vieille classe, à partir de JDK 1.0.Les classes qui sont en place à partir de JDK 1.0 sont appelées Legacy classes et par défaut elles sont synchronisées .

Pour comprendre cela, vous devez tout d'abord comprendre les commentaires écrits sur cette classe par l'auteur . “Cette classe implémente une table de hachage, qui associe les clés aux valeurs. Tout objet non nul peut être utilisé comme clé ou comme valeur. Pour stocker et récupérer des objets d'une table de hachage, les objets utilisés en tant que clés doivent implémenter la méthode hashCode et la méthode equals. ”

La classe HashTable est implémentée sur un mécanisme de hachage, qui consiste à stocker toute paire clé-valeur, son code de hachage requis de l'objet clé. HashTable calcule un hachage pour chaque clé en appelant hashCode sur chaque clé. Cela échouerait Si key était null, il ne pourrait pas donner de hachage pour la clé null, il lèverait NullPointerException et similaire est le cas pour value, renvoyant null si la valeur est null.

Mais plus tard, on s'est rendu compte que la clé et la valeur nulles avaient leur propre importance, puis des implémentations révisées de HashTable ont été introduites, comme HashMap, qui autorisent une clé nulle et plusieurs valeurs nulles.

Pour HashMap, il autorise une clé nulle et il y a une vérification nulle pour les clés. Si la clé est nulle, cet élément sera stocké à un emplacement zéro dans le tableau Entry. 

Nous ne pouvons pas avoir plus d'une clé Null dans HashMap car Les clés sont uniques pour cette raison, une seule clé Null et de nombreuses valeurs Null sont autorisées.

USE- Clé nulle pouvant être utilisée avec certaines valeurs par défaut.

Une mise en œuvre modifiée et améliorée de HashTable a ensuite été introduite sous la forme/ ConcurrentHashMap .

3
shubham malik

Outre les réponses de Mark Bayers, la valeur Null est considérée comme une donnée et doit être stockée en tant que valeur pour un contrôle ultérieur. Dans de nombreux cas, null as value peut être utilisé pour vérifier si une entrée de clé est présente mais aucune valeur ne lui est affectée. Par conséquent, certaines actions peuvent être entreprises en conséquence. Cela peut être fait en vérifiant d’abord si la clé est là, puis en obtenant de la valeur ... Il y a encore un cas dans lequel il suffit de mettre toutes les données qui arrivent (sans aucun contrôle). Toutes les vérifications sont appliquées après l'avoir obtenu.

Alors que null en tant que clé, je pense que l’on peut utiliser pour définir certaines données par défaut. Habituellement, la valeur null en tant que clé n'a pas beaucoup de sens.

2
Amit Agrawal

Monsieur HashMap utilise également en interne la méthode hashCode () pour insérer un élément dans HashMap. Je pense donc que ce ne sera pas la bonne raison pour "pourquoi HashTable autorise-t-elle la clé nulle"

1
user3207104

Cela rendra l’utilisation plus simple de l’interface de la carte. null est une valeur légitime pour les types de référence. Rendre la carte capable de gérer des clés et des valeurs nulles éliminera le besoin de vérifier les valeurs nulles avant d'appeler l'api. Ainsi, les cartes api créent moins de "surprises" lors de l'exécution.

Par exemple, il est courant que la carte soit utilisée pour catégoriser une collection d'objets homogènes basée sur un seul champ. Lorsque map est compatible avec null, le code sera plus concis puisqu'il ne s'agit que d'une simple boucle sans instruction if (vous devrez bien sûr vous assurer que la collection ne contient pas d'éléments null). Moins de lignes de code sans traitement de branche/exception seront plus susceptibles d'être logiquement correctes.

D'autre part, ne pas autoriser la valeur NULL ne rendra pas l'interface de carte meilleure/plus sûre/plus facile à utiliser. Il n’est pas pratique de s’appuyer sur la carte pour rejeter les valeurs NULL - cela signifie que l’exception sera levée et que vous devez la capturer et la gérer. Ou bien, pour vous débarrasser de l'exception, vous devrez vous assurer que rien n'est null avant d'appeler les méthodes de la carte. Dans ce cas, vous ne vous souciez pas de savoir si map accepte null, car vous avez quand même filtré l'entrée.

0
Xinchao