"Peut-être que le problème n'est pas que rien ne nous dérange, mais que nous le dérangeons."
bmargulies
3
Dans Guava, les collections google, de nombreuses classes n'autorisent pas la valeur null et le raisonnement derrière cela est que 95% des cas n'ont pas besoin de null et peuvent représenter des bogues, potentiellement difficiles à trouver.
stivlo
Une chose étrange est que ConcurrentHashMapcela ne prend pas en charge les clés nulles, alors que le HashMapfait.
codepleb
2
Seul HashMap autorise null :)
subhashis
Réponses:
126
Je ne suis pas sûr de ce que vous demandez, mais si vous cherchez un exemple de cas où l'on voudrait utiliser une clé nulle, je les utilise souvent dans les cartes pour représenter le cas par défaut (c'est-à-dire la valeur à utiliser si une clé donnée n'est pas présente):
Map<A, B> foo;
A search;
B val = foo.containsKey(search)? foo.get(search): foo.get(null);
HashMapgère spécialement les clés nulles (car il ne peut pas appeler .hashCode()un objet nul), mais les valeurs nulles ne sont rien de spécial, elles sont stockées dans la carte comme toute autre chose
Donc, si .hashCode () n'est pas possible sur null, qui décide dans quel chariot la touche null entrera?
Pacerier
26
@Pacerier Il y a une méthode spéciale dans HashMap( putForNullKey) qui le gère; il le stocke dans la table 0
Michael Mrozek
1
@MichaelMrozek votre dernière ligne B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);Je pense que nous pouvons simplement appeler la méthode get sur la clé de recherche qui aura le même résultat. B val = foo.get(search);pourriez-vous s'il vous plaît me corriger si je me trompe?
dheerajraaj le
6
@ dheeraj92 Votre code sera défini valsur nullsi la clé n'existe pas; le mien le définit sur n'importe quelle nullcarte sur la carte. C'était le point, je stocke une valeur non nulle par défaut à la nullclé de la carte et l'utilise si la clé réelle n'existe pas
Michael Mrozek
28
Un exemple serait la modélisation des arbres. Si vous utilisez un HashMap pour représenter une arborescence, où la clé est le parent et la valeur est la liste des enfants, les valeurs de la nullclé sont les nœuds racine.
Un exemple d'utilisation des nullvaleurs est l'utilisation de a HashMapcomme cache pour les résultats d'une opération coûteuse (comme un appel à un service Web externe) qui peut retourner null.
Mettre une nullvaleur dans la carte permet alors de distinguer le cas où l'opération n'a pas été effectuée pour une clé donnée ( cache.containsKey(someKey)retourne false), et où l'opération a été effectuée mais a renvoyé une nullvaleur ( cache.containsKey(someKey)retourne true, cache.get(someKey)retourne null).
Sans nullvaleurs, vous devrez soit mettre une valeur spéciale dans le cache pour indiquer une nullréponse, soit simplement ne pas mettre en cache cette réponse du tout et effectuer l'opération à chaque fois.
Les réponses jusqu'à présent ne considèrent que la valeur d'une nullclé, mais la question pose également des questions any number of null values.
L'avantage de stocker la valeur par nullrapport à une clé dans un HashMap est le même que dans les bases de données, etc. - vous pouvez enregistrer une distinction entre avoir une valeur qui est vide (par exemple, une chaîne "") et ne pas avoir de valeur du tout (null) .
Voici mon seul exemple quelque peu artificiel d'un cas où la nullclé peut être utile:
publicclassTimer{privatestaticfinalLogger LOG =Logger.getLogger(Timer.class);privatestaticfinalMap<String,Long> START_TIMES =newHashMap<String,Long>();publicstaticsynchronizedvoid start(){long now =System.currentTimeMillis();if(START_TIMES.containsKey(null)){
LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(null).longValue())+"ms");}
START_TIMES.put(null, now);}publicstaticsynchronizedlong stop(){if(! START_TIMES.containsKey(null)){return0;}return printTimer("Anonymous", START_TIMES.remove(null),System.currentTimeMillis());}publicstaticsynchronizedvoid start(String name){long now =System.currentTimeMillis();if(START_TIMES.containsKey(name)){
LOG.warn(name +" timer was started twice without being stopped; previous timer has run for "+(now - START_TIMES.get(name).longValue())+"ms");}
START_TIMES.put(name, now);}publicstaticsynchronizedlong stop(String name){if(! START_TIMES.containsKey(name)){return0;}return printTimer(name, START_TIMES.remove(name),System.currentTimeMillis());}privatestaticlong printTimer(String name,long start,long end){
LOG.info(name +" timer ran for "+(end - start)+"ms");return end - start;}}
Si vous essayez d'arrêter un minuteur inexistant ou qui a déjà été arrêté, cela devrait être une erreur, non ignorée.
Fonder le procès de Monica le
@QPaysTaxes - Dépend de votre intention. Si vous voulez un utilitaire léger qui peut être facilement utilisé, vous ne voulez généralement pas le fairethrow Exception . En outre, ce n'est pas comme si tenter d'arrêter une minuterie inexistante ou déjà arrêtée est quelque chose dont l'appelant peut généralement récupérer.
aroth
1
Autre exemple: je l'utilise pour regrouper les données par date. Mais certaines données n'ont pas de date. Je peux le regrouper avec l'en-tête "NoDate"
Une clé nulle peut également être utile lorsque la carte stocke des données pour les sélections d'interface utilisateur où la clé de carte représente un champ de bean.
Une valeur de champ nulle correspondante serait par exemple représentée par "(veuillez sélectionner)" dans la sélection de l'interface utilisateur.
ConcurrentHashMap
cela ne prend pas en charge les clés nulles, alors que leHashMap
fait.Réponses:
Je ne suis pas sûr de ce que vous demandez, mais si vous cherchez un exemple de cas où l'on voudrait utiliser une clé nulle, je les utilise souvent dans les cartes pour représenter le cas par défaut (c'est-à-dire la valeur à utiliser si une clé donnée n'est pas présente):
HashMap
gère spécialement les clés nulles (car il ne peut pas appeler.hashCode()
un objet nul), mais les valeurs nulles ne sont rien de spécial, elles sont stockées dans la carte comme toute autre chosela source
HashMap
(putForNullKey
) qui le gère; il le stocke dans la table 0B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);
Je pense que nous pouvons simplement appeler la méthode get sur la clé de recherche qui aura le même résultat.B val = foo.get(search);
pourriez-vous s'il vous plaît me corriger si je me trompe?val
surnull
si la clé n'existe pas; le mien le définit sur n'importe quellenull
carte sur la carte. C'était le point, je stocke une valeur non nulle par défaut à lanull
clé de la carte et l'utilise si la clé réelle n'existe pasUn exemple serait la modélisation des arbres. Si vous utilisez un HashMap pour représenter une arborescence, où la clé est le parent et la valeur est la liste des enfants, les valeurs de la
null
clé sont les nœuds racine.la source
Un exemple d'utilisation des
null
valeurs est l'utilisation de aHashMap
comme cache pour les résultats d'une opération coûteuse (comme un appel à un service Web externe) qui peut retournernull
.Mettre une
null
valeur dans la carte permet alors de distinguer le cas où l'opération n'a pas été effectuée pour une clé donnée (cache.containsKey(someKey)
retournefalse
), et où l'opération a été effectuée mais a renvoyé unenull
valeur (cache.containsKey(someKey)
retournetrue
,cache.get(someKey)
retournenull
).Sans
null
valeurs, vous devrez soit mettre une valeur spéciale dans le cache pour indiquer unenull
réponse, soit simplement ne pas mettre en cache cette réponse du tout et effectuer l'opération à chaque fois.la source
Les réponses jusqu'à présent ne considèrent que la valeur d'une
null
clé, mais la question pose également des questionsany number of null values
.L'avantage de stocker la valeur par
null
rapport à une clé dans un HashMap est le même que dans les bases de données, etc. - vous pouvez enregistrer une distinction entre avoir une valeur qui est vide (par exemple, une chaîne "") et ne pas avoir de valeur du tout (null) .la source
Voici mon seul exemple quelque peu artificiel d'un cas où la
null
clé peut être utile:la source
throw Exception
. En outre, ce n'est pas comme si tenter d'arrêter une minuterie inexistante ou déjà arrêtée est quelque chose dont l'appelant peut généralement récupérer.Autre exemple: je l'utilise pour regrouper les données par date. Mais certaines données n'ont pas de date. Je peux le regrouper avec l'en-tête "NoDate"
la source
Une clé nulle peut également être utile lorsque la carte stocke des données pour les sélections d'interface utilisateur où la clé de carte représente un champ de bean.
Une valeur de champ nulle correspondante serait par exemple représentée par "(veuillez sélectionner)" dans la sélection de l'interface utilisateur.
la source