2010-04-21 6 views
1

je le TreeMap suivant:TreeMap cesse de façon aléatoire retourner correctement les valeurs

TreeMap<String, Integer> distances = new TreeMap<String, Integer>(); 

et il contient les deux chaînes, "Face" et "Foo", avec des valeurs appropriées, telles que:

System.out.println(distances); 

rendement:

{Face=12, Foo=2} 

Cependant, distances.get(Face) retours null, bien que distances.get(Foo) renvoie correctement 2. Auparavant, distances.get(Face) travaillé, mais pour une raison quelconque, il a cessé de fonctionner. Remarque: J'imprime la carte à droite avant d'appeler get() pour les deux clés, donc je n'ai pas accidentellement changé la valeur de Face à null. Est-ce que quelqu'un d'autre a déjà rencontré ce problème? Y a-t'il quelque chose que je puisse faire? J'ai du mal à essayer de comprendre comment résoudre ce problème.

REMARQUE: Dans le code réel, je n'utilise pas réellement les chaînes, mais un objet différent, donc c'est: TreeMap<Object, Integer>. Il ne s'agit donc pas simplement d'une confusion entre les noms de variables et les chaînes littérales.

DEUXIÈME NOTE: Je me sens également assez confiant quant à mes implémentations de hashcode() et equals() pour l'objet que j'utilise. (De plus, si mes implémentations n'étaient pas correctes, cela ne fonctionnerait-il pas au début?)

+0

Avez-vous un accès synchronisé à la carte? Peut-être que les valeurs ont été supprimées par un autre thread? –

+0

Non, je n'ai pas synchronisé l'accès, mais je ne pense pas que je dois le faire. Fondamentalement, les appels sont dans une boucle for simple qui itère sur toute la carte. Il ne fait rien mais fait appel à get() pour les comparaisons. – smessing

+1

-1 - supprimez cette question et recommencez avec le problème REAL, pas de non-sens à propos de TreeMap 'ne fonctionnant pas. Et incluez assez de votre code actuel pour nous donner un indice ... –

Répondre

5

En réponse à votre note: tout le monde vous demande si vous avez surchargé equals() et hashcode() correctement - ce qui est important, oui. Mais ceci est un TreeMap, ce qui signifie que vous devez également vous soucier des comparaisons - que vous utilisiez des objets Comparable ou un Comparator externe, vous devez vous assurer que vos comparaisons sont cohérentes (vos objets sont-ils mutables?) Et qu'ils ' re compatible avec votre méthode equals(). Incidemment, quand vous avez dit dans votre question initiale que vous utilisiez des objets String, vous vous êtes rendu un mauvais service - Les cordes sont immuables et leurs méthodes de comparaison ne sont pas à l'étude ici, donc la question était fondamentalement différente; Maintenant que nous savons que votre propre code est impliqué, le champ des solutions possibles est plus large.

+0

Je vois votre point sur la mention des objets 'String', désolé à ce sujet. En ce qui concerne votre commentaire, je ne suis pas sûr que je suis. Que voulez-vous dire par «assurez-vous que vos comparaisons sont cohérentes» ... assurez-vous que mes objets ne changent pas sans que je m'en aperçoive? Si c'est le cas, je suis également assez confiant que les objets eux-mêmes ne changent pas du tout. Le code tout est dans le tri entre les objets, mais pas pour les * opérer * sur eux, si cela a du sens. – smessing

0

Etes-vous sûr que les valeurs "Foo" et "Face" sont toutes les deux Strings?

Ce code fonctionne pour moi:

 TreeMap<String, Integer> map = new TreeMap<String, Integer>(); 
     map.put("a", 1); 
     map.put("b", 2); 

     System.out.println(map); 
     System.out.println(map.get("a")); 
     System.out.println(map.get("b")); 

Will sortie {a = 1, b = 2} 2.

Dans votre cas, si Foo et Face ne sont pas les deux String s , la carte ne peut pas les utiliser comme clés pour une recherche. Peut-être que vous utilisez get(Face) où vous devriez utiliser get("Face")?

+0

Voir le commentaire sur l'autre réponse, mais fondamentalement, je n'utilise pas réellement les chaînes, j'utilise un type de données différent. Les cordes étaient à des fins d'illustration. – smessing

0

Confondrez-vous la chaîne littérale "Face" avec une variable appelée Face? Si vous utilisez littéralement distances.get(Face), cela signifie que vous essayez de transmettre une variable Face, et il n'est pas surprenant que vous obteniez null de retour (sauf s'il s'agit d'une variable String dont contenu vous avez précédemment ajouté à la carte).

Essayez plutôt distances.get("Face"). Si cela fonctionne, cela signifie que "Face" est la chaîne que vous utilisez comme une clé - ce qui n'est pas la même chose qu'une variable Face pouvant contenir une chaîne.

+0

Désolé, cela demande une clarification: dans mon code actuel, j'utilise différents objets (mon propre type de données), donc la confusion dont vous parlez ne peut pas être ce qui se passe. – smessing

0

@smessing avez-vous implémenté correctement les méthodes equals et hashcode sur votre classe auxquelles appartiennent les objets Foo et Face? Lorsque vous souhaitez stocker un objet dans une liste, une carte ou un ensemble, il est nécessaire que equals et hashCode soient implémentés pour qu'ils respectent le contrat standard spécifié dans la documentation. Si ces opérations ne sont pas effectuées correctement, une opération get peut entraîner des résultats inattendus, comme vous l'avez mentionné.

+0

J'ai mis en œuvre les deux, et je suis assez confiant que ce n'est pas le problème. De plus, rappelez-vous que pendant un certain temps, les appels get() renvoient les valeurs correctes, mais à un certain point, ils arrêtent ... – smessing

+0

-1 - hashCode n'est pas pertinent pour un TreeMap! –

0

Si vous affectez Face à un autre objet/variable de référence, vérifiez si cela devient nul.

Si votre objet face pointe vers la référence d'un autre objet et que l'autre objet le définit sur null, Face devient également nul.

Questions connexes