2017-01-19 15 views
0

containsKey関数を使用していくつか問題が発生しています。私はのcontainsKeyが私に異なる結果を与えることを期待しています場所を示すための小さなプログラムを書いた: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(); 
} 

次のように識別子クラスのコンストラクタは、initは()似ているが、それはにあったものを削除します前の識別子。

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

私はキーとして識別子を使用してハッシュマップに何かを置くが、私は別の名前ではなく、私は本当のを期待していた場合のcontainsKey関数がfalseを返した同じ内容の識別子を使用しようとします。 (出力はtrueを返します false

ありがとうございます!

+0

あなたはwork変数を無視することができます。コードからその変数を削除するのを忘れました – Marnix

答えて

1

識別子オブジェクトにはequals()hashCode()を実装します。関連するバケットを見つけるにはhashCodeが必要で、ハッシュ中に衝突を処理するにはequalsが必要です。結果はオブジェクトのみa時間あれば、trueになることを私たちに語ったgetEntryHashMap.class

/** 
* 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; 
} 

方法getEntry

/** 
    * 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; 
    } 

HashMap.classにおける方法で

Further Reading

+1

理想的には、あなたのキーは「不変」であるべきです。したがって、挿入後に何らかの方法でキーを変更している場合は、もう一度同様の問題に遭遇します。 – Rubbal

+0

私はこれらのメソッドを調べました。正しく理解すれば、識別子が同じかどうかをブール値を返す関数を(識別子クラス内で)作成する必要があります。それは次のようなものでしょうか?public boolean equals(IdentifierInterface iden1、IdentifierInterface iden2) ハッシュコードに関しては、実装方法のヒントを教えてください。ハッシュコード関数に関する情報は、それを私に明確にしません。 – Marnix

+0

この場合、単に 'Character.hashCode(c)'を返すことができます。引数に 'c'でオブジェクトが指定されているので、後でバッファを変更しないでください。 – Rubbal

0

方法containsKey同じhashCode()オブジェクトとしてba.equals(b)

+0

私はイコールダウンしていると思う。 hashCode()だけが完全にわかりません。 – Marnix

+0

私はまだそのコメントに取り組んでいた – Marnix

+0

私はそのSystem.out.printlnを参照してください(iden.hashCode());およびSystem.out.println(newIden.hashCode()); getEntryが正しく機能するためには同じである必要がある異なるハッシュコードを生成しています。私は答えを探してこのサイトにアクセスしましたhttps://coderanch.com/t/612036/java/hashcode-equal-objectsしかし、同じ値を持つ2つの異なるオブジェクトが同じハッシュコードを取得するようです。なぜ同じ値を持つ識別子オブジェクトも同じハッシュコードを持っていないのですか? – Marnix

関連する問題