2012-04-23 1 views
1

Quand java appelle la méthode get de hashmap java effectue une comparaison equals()? J'ai lu que c'est le cas mais avec les erreurs que je reçois, il semble que ce soit une comparaison ===.Comment fonctionne get() sur hashmap

public class UniversalFiniteStateAutomaton {

State currentState; 
State initialState; 
State trapState; 

public UniversalFiniteStateAutomaton(ArrayList<String> finalStates, 
     ArrayList<String> transitions) { 
    String statesAndTransitions[]; 
    Map<Symbol<E>, State> createdStates = new HashMap<Symbol<E>, State>(); 
    for (String s : transitions) { 
     // Replace the stuff that doesn't matter 
     s = s.replaceAll("[()]", ""); 
     // Split the transition into states and transitions 
     statesAndTransitions = s.split("\\s+"); 

     // Create the state if its not already created 
     if (finalStates.contains(new Symbol(statesAndTransitions[0]))) { 
      if (!createdStates.containsKey((new Symbol(statesAndTransitions[0])))) { 
       createdStates.put(new Symbol(statesAndTransitions[0]), 
         new FinalState(this)); 
       System.out.println("Created one symb " + new Symbol(statesAndTransitions)); 
      } 
     } else { 
      if (!createdStates.containsKey(new Symbol(statesAndTransitions[0]))) { 
       createdStates.put(new Symbol(statesAndTransitions[0]), 
         new NormalState(this)); 
       System.out.println("Created one symb " + new Symbol(statesAndTransitions[0])); 
      } 
     } 
     // Make sure that the next state is created 
     if (finalStates.contains(new Symbol(statesAndTransitions[2]))) { 
      if (!createdStates.containsKey(new Symbol(statesAndTransitions[2]))) { 
       createdStates.put(new Symbol(statesAndTransitions[2]), 
         new FinalState(this)); 
      } 
     } else { 
      if (!createdStates.containsKey(new Symbol(statesAndTransitions[2]))) { 
       createdStates.put(new Symbol(statesAndTransitions[2]), 
         new NormalState(this)); 
      } 
     } 

     System.out.println(createdStates); 
     // Define the transition 
     createdStates.get(new Symbol(statesAndTransitions[0])).addTransition(
       new Symbol(statesAndTransitions[1]), 
       createdStates.get(new Symbol(statesAndTransitions[2]))); 

    } 
    this.currentState = createdStates.get(new Symbol("0")); 
} 

public String analyzeInput(String input) { 
    String splitInput[] = input.split("\\s+"); 
    for(String s: splitInput) 
     try { 
      currentState.transition(new Symbol(s)); 
     } catch (TrapException e) { 
      return("Reject"); 
     } 
    if(currentState.type()==0) 
     return "Accept"; 
    return "Reject"; 
} 


public void setState(State currentState) { 
    this.currentState = currentState; 
} 
} 




public class Symbol<E> { 
private E symbol; 

public Symbol(E symbol){ 
    this.symbol = symbol; 
} 

public E getSymbol() { 
    return symbol; 
} 

public void setSymbol(E symbol) { 
    this.symbol = symbol; 
} 

public String toString(){ return "" +symbol;} 

}

+1

plus d'informations nécessaires ... qu'est-ce que vous essayez de faire exactement? les extraits de code seraient également utiles – giorashc

+0

Veuillez nous indiquer votre code et les erreurs exactes que vous obtenez. [Avez-vous implémenté à la fois 'equals' et' hashCode' correctement sur vos objets clés?] (Http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java) –

+0

Une autre chose importante à considérer est que les clés HashMap doivent être immuables (au moins aussi longtemps qu'elles sont dans la carte). Si une clé change son hashCode après qu'elle a été placée dans HashMap, la recherche ne fonctionnera pas très bien. – Thilo

Répondre

3

Oui, il le fait. Cependant, si vous ne définissez pas votre propre equals() pour votre propre classe, il utilise Object.equals(), et utilise ==. C'est pourquoi vous devez remplacer equals() (et hashcode()) si jamais vous voulez placer vos objets dans une collection.

+0

si vous voulez utiliser votre objet comme clé dans un HashMap. D'autres utilisations dans Collections peuvent convenir à l'implémentation par défaut. – Thilo

+1

Il est trop large de dire que vous devez remplacer 'equals' et 'hashCode' si vous voulez placer des objets dans une collection. Vous n'avez pas besoin de surcharger pour les mettre dans une 'Liste'; Si vous voulez les placer dans un TreeMap ou un TreeSet, vous devez remplacer equals, mais pas hashCode, mais vous devez probablement implémenter 'Comparable'. –

+0

@TomAnderson: Vous pouvez toujours avoir 'equals' dans une' List' si vous voulez utiliser des choses comme 'indexOf'. – Thilo

2

Il utilise hashcode() pour localiser les correspondances potentielles et utilise ensuite égal pour trouver la correspondance exacte. Si son objet défini par l'utilisateur s'assure que les deux égaux et hashcode sont mis en œuvre pour honorer le contrat (mentionné dans la documentation de classe de l'objet).

1

utilise d'abord obtenir == pour vérifier que peut-être il est le même objet. Sinon, il utilise égal.

Voir le code ici http://www.docjar.com/html/api/java/util/HashMap.java.html

/** 
    298  * Returns the value to which the specified key is mapped, 
    299  * or {@code null} if this map contains no mapping for the key. 
    300  * 
    301  * <p>More formally, if this map contains a mapping from a key 
    302  * {@code k} to a value {@code v} such that {@code (key==null ? k==null : 
    303  * key.equals(k))}, then this method returns {@code v}; otherwise 
    304  * it returns {@code null}. (There can be at most one such mapping.) 
    305  * 
    306  * <p>A return value of {@code null} does not <i>necessarily</i> 
    307  * indicate that the map contains no mapping for the key; it's also 
    308  * possible that the map explicitly maps the key to {@code null}. 
    309  * The {@link #containsKey containsKey} operation may be used to 
    310  * distinguish these two cases. 
    311  * 
    312  * @see #put(Object, Object) 
    313  */ 
    314  public V get(Object key) { 
    315   if (key == null) 
    316    return getForNullKey(); 
    317   int hash = hash(key.hashCode()); 
    318   for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
    319    e != null; 
    320    e = e.next) { 
    321    Object k; 
    322    if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 
    323     return e.value; 
    324   } 
    325   return null; 
    326  } 
+0

@ PéterTörök: Mauvais. Ligne 322. –

+0

Pourquoi regarder si (e.hash == hash && ((k = e.key) == clé || key.equals (k))) –

0

hashmap utilise le hashcode() pour trouver le seau appropirate premier et si elle trouve plus d'une entrée dans le seau alors il a utilisé la méthode égale.

Si vous ne définissez pas la méthode equals dans votre classe selon votre requirment, elle utilisera la définition de la classe parente Object, qui est une simple opération "==".

Il est toujours préférable de remplacer le hashcode et la méthode égale si vous utilisez votre classe comme clé dans hashmap.

Questions connexes