2010-12-10 4 views
1

J'ai le code suivant:Pourquoi containsKey n'a pas trouvé la clé?

payoffs2exchanges.put(point, exchange); 
if (!payoffs2exchanges.containsKey(point)) { 
    game.log.fine("yes"); 
} else { 
    game.log.fine("no"); 
} 

Il produit "non". En d'autres termes, j'ajoute la paire clé-valeur à la carte, puis, immédiatement après, je vérifie si la clé existe et découvre qu'elle n'existe pas. Pourquoi?

J'ai toujours le problème avec la clé. Le code suivant indique chaque fois que j'ajoute une clé, j'ajoute une nouvelle clé. Et je sais que ce n'est pas le cas.

 Integer[] point = new Integer[2]; 
     point[0] = proposerBestScore; 
     point[1] = responderBestScore; 
     game.log.fine("In the getCloudOfPayoffs: found payoffs:" + point[0] + "," + point[1] + ". Exchange: " + exchange[0]+","+exchange[1]+","+exchange[2]+","+exchange[3]+","+exchange[4]); 
     // With the following block we ensure that every options (pair of payoffs) is represented by exchange with minimal number of moves. 
     if (!payoffs2exchanges.containsKey(point)) { 
      payoffs2exchanges.put(point, exchange); 
      game.log.fine("In the getCloudOfPayoffs: this option is new. We add it to the map."); 
     } else { 
      game.log.fine("In the getCloudOfPayoffs: this option is old."); 
      Integer[] exchangeFromMap = payoffs2exchanges.get(point); 
      Integer newSum = 0; 
      Integer oldSum = 0; 
      for (int i=0;i<Design.nColors;i++) { 
       newSum = newSum + Math.abs(exchange[i]); 
       oldSum = oldSum + Math.abs(exchangeFromMap[i]); 
      } 
      if (newSum<oldSum) { 
       game.log.fine("In the getCloudOfPayoffs: the new exchange is better than the old one."); 
       payoffs2exchanges.put(point, exchange); 
      } 
     } 
+0

De quelle classe est 'point'? Classe personnalisée? Quelle classe est 'payoffs2exchanges'? –

+0

Ajout d'une réponse à votre mise à jour. – aioobe

+0

@aioobe, désolé pour ces manipulations avec la question. Je le remets. Donc, vous répondez est utile. – Roman

Répondre

6

Vous utilisez un Integer[] comme clé dans la carte. C'est une mauvaise chose, puisque les tableaux Java n'implémentent pas equals et hashCode comme vous pouvez vous y attendre. Voir cet exemple:

public class Test { 
    public static void main(String[] args) { 
     Integer[] arr1 = { 1, 2 }; 
     Integer[] arr2 = { 1, 2 }; 

     System.out.println(arr1.equals(arr2)); 
     System.out.println(arr1.hashCode() + "/" + arr2.hashCode()); 
    } 
} 

Sur mon ordinateur, il imprime:

false 
1476323068/535746438 

Ma recommandation est de créer une classe qui remplace correctement personnalisée Pointequals et hashCode (ou éventuellement réutiliser java.awt.Point si vous pensez que marques sens).

+0

cela signifie-t-il que containsKey ne fonctionne pas si j'utilise tableau entier comme une clé? – Roman

+0

Oui, exactement. Les cartes en général s'appuient fortement sur la méthode 'equals', et quand il s'agit par exemple de' HashMap', le 'hashCode' est également important. – aioobe

+0

mais puis-je toujours utiliser 'somHashMap.get (clé)' si la clé est un tableau d'entiers? – Roman

6

Il est faire la bonne chose. containsKey renvoie true, l'opérateur ! l'annule à false, et donc il sort no (la clause else).

+0

Merci! C'était une question stupide. – Roman

+0

Bienvenue. Je suppose que c'était une erreur imprudente .. – lijie

0

Regardez votre code :) il imprime no si la carte contient en fait la clé ...