2017-01-19 3 views
0

Ich habe einige Probleme mit der Funktion containsKey. Ich schrieb ein kleines Programm zu zeigen, wo ich containsKey erwarten ein anderes Ergebnis geben Sie mir:Java util hashmap containsKey()

HashMap<IdentifierInterface, Set<NaturalNumberInterface>> hashMap; 
HashMap<StringBuffer, Integer> works; 

TryHashmap(){ 
    hashMap = new HashMap<IdentifierInterface, Set<NaturalNumberInterface>>(); 
    works = new HashMap<StringBuffer, Integer>(); 
} 
private void start() {  
    Identifier iden = new Identifier('a'); 
    NaturalNumber nn = new NaturalNumber('8'); 
    Set<NaturalNumberInterface> set = new Set<NaturalNumberInterface>(); 
    set.insert(nn); 

    hashMap.put(iden, set); 
    System.out.println(hashMap.containsKey(iden)); 

    Identifier newIden = new Identifier('a'); 
    System.out.println(hashMap.containsKey(newIden)); //TODO why is this not true? 

    iden.init('g'); 
    System.out.println(hashMap.containsKey(iden)); 
} 

public static void main(String[] argv) { 
    new TryHashmap().start(); 
} 

Der Konstruktor der Identifier Klasse wird wie folgt, die init() ähnlich ist, aber es wird alles zu entfernen, war in die Kennung vor.

Identifier(char c){ 
    iden = new StringBuffer(); 
    iden.append(c); 
} 

Ich habe etwas in die hashmap einen Identifier als Schlüssel verwendet, aber wenn ich versuche, eine Identifikation mit einem anderen Namen zu verwenden, aber mit dem gleichen Inhalt der containsKey Funktion gibt false zurück, wo ich ein wahres erwarten. (der Ausgang druckt true false wahr)

Vielen Dank im Voraus!

+0

können Sie die Werke Variable ignorieren, vergessen zu i – Marnix

Antwort

1

Implementieren Sie equals() und hashCode() für das Bezeichnerobjekt. hashCode wird benötigt, um den relevanten Bucket zu finden, und equals wird benötigt, um Kollisionen beim Hashing zu behandeln.

Further Reading

+1

Im Idealfall, dass man aus dem Code zu entfernen, sollten Sie Ihre Schlüssel sein 'Immutable'. Wenn Sie den Schlüssel also nach dem Einfügen ändern, werden Sie wieder auf ähnliche Probleme stoßen. – Rubbal

+0

Ich habe diese Methoden nachgeschlagen, wenn ich das richtig verstanden habe, muss ich eine Funktion (in der Bezeichner-Klasse) erstellen, die einen Boolean zurückgibt, ob die Bezeichner identisch sind. Wäre das etwas wie: public boolean equals (IdentifierInterface iden1, IdentifierInterface iden2) Wie für den Hashcode, könnten Sie mir einen Hinweis geben, wie Sie es implementieren können. Die Informationen über die Hashcode-Funktion machen es mir nicht klarer ... – Marnix

+0

In diesem Fall können Sie einfach 'Character.hashCode (c)' zurückgeben. Beachten Sie, dass Sie den Puffer später nicht mehr ändern sollten, da das Objekt im Argument mit "c" gekennzeichnet ist. – Rubbal

0

Methode containsKeyHashMap.class in

/** 
* Returns <tt>true</tt> if this map contains a mapping for the 
* specified key. 
* 
* @param key The key whose presence in this map is to be tested 
* @return <tt>true</tt> if this map contains a mapping for the specified 
* key. 
*/ 
public boolean containsKey(Object key) { 
    return getEntry(key) != null; 
} 

Methode getEntry in HashMap.class

/** 
    * Returns the entry associated with the specified key in the 
    * HashMap. Returns null if the HashMap contains no mapping 
    * for the key. 
    */ 
    final Entry<K,V> getEntry(Object key) { 
     int hash = (key == null) ? 0 : hash(key.hashCode()); 
     for (Entry<K,V> e = table[indexFor(hash, table.length)]; 
      e != null; 
      e = e.next) { 
      Object k; 
      if (e.hash == hash && 
       ((k = e.key) == key || (key != null && key.equals(k)))) 
       return e; 
     } 
     return null; 
    } 

das Verfahren getEntry uns gesagt, dass das Ergebnis true sein wird, nur wenn das Objekt a h als die gleiche hashCode() wie das Objekt b und a.equals(b)

+0

Ich denke, ich habe die Gleichgestellten runter. Nur der hashCode() ist mir nicht völlig klar. – Marnix

+0

Verzeihung, ich arbeitete immer noch an diesem Kommentar – Marnix

+0

Ich sehe, dass System.out.println (iden.hashCode()); und System.out.println (newIden.hashCode()); produzieren unterschiedliche Hashcodes, die gleich sein müssen, damit der getEntry ordnungsgemäß funktioniert. Ich suchte nach Antworten und kam auf diese Seite https://codeanch.com/t/612036/java/hashcode-equal-objects, aber es scheint, dass zwei verschiedene Objekte mit dem gleichen Wert den gleichen Hashcode bekommen. Warum hat mein Identifikatorobjekt mit den gleichen Werten nicht auch den gleichen Hashcode? – Marnix