2011-07-29 5 views
8
public class Contact 
{ 
    int i; 
    String name; 
    public Contact(int iVal, String nameVal) 
    { 
     i = iVal; 
     name = nameVal; 
    } 
} 

public class MultiMap 
{ 
    public static void main (String args[]) 
    { 
     java.util.HashMap m = new java.util.HashMap(); 
       Contact m1 = new Contact(1, "name"); 
     Contact m2 = new Contact(1, "name"); 
     m.put(m1, "first"); 
     m.put(m2, "second"); 
     System.out.println(m.get(m1)); 
     System.out.println(m.get(m2)); 
    } 
} 

出力は次のとおりです。ハッシュコードなしの地図キーなどのオブジェクトと等しい

first 
second 

どのようにこの「取得する」方法が振る舞うのか? m1とM2は同じ値を持ち、hashcode()をオーバーライドしていないため、Objectクラスのequals()メソッドが呼び出されますか?

これは間違いありませんか?

  • そこには、メソッドので、クラスの等号を(オブジェクトの上書き)が呼び出され等しくされ、オブジェクトのM1とM2は異なる値が含まれている場合、JVMが参照する方法がないので、

    1. 何のhashCodeメソッドはありません両方のオブジェクトとして上記のコードはm1の値をm2に置き換えずに正常に動作します。
  • 答えて

    8

    hashCode()equals(Object o)メソッドはクラスによって上書きされていない場合は、Javaは単に値を計算するためにメモリ内のオブジェクトへの実際の参照を使用しています(すなわち。それはクラスの同じインスタンス化であるかどうかをチェック)。それで、あなたはまだ両方の結果を得るのです。

    0

    Contactクラスでは、hashcode()equals()の機能を実装していません。

    これらのメソッドをHashMapが呼び出すと、この場合はObjectである親クラスのメソッドが検索されます。

    この場合、値の代わりにヒープ上のオブジェクトの位置が評価されます。

    二つのオブジェクトo1o2

    o1.equals(o2) == trueのみo1 == o2

    hashCode()

    は、オブジェクト・クラスのメソッドである場合。ハッシュコードは、JVMによるオブジェクトの整数表現です。ハッシュコードはシステム生成され、JVMはハッシュコードを生成するための基底(シード)としてオブジェクトのアドレスを取得します。生成されたハッシュコードは、異なる実行時間で同じである必要はありません。

    0

    はいこれは正しいです。独自のequalsおよびhashcodeメソッドを定義していないjavaオブジェクトは、java.lang.Objectのデフォルトのequalsおよびhascodeメソッドを継承します。これらのデフォルトの実装は、オブジェクト参照の等価性に基づいており、論理的に等価ではありません。同じオブジェクト参照でgetを呼び出したので、オブジェクトはマップから返されます。

    これは、これをさらに詳しく示す例です。

    java.util.HashMap m = new java.util.HashMap(); 
    Contact m1 = new Contact(1, "name"); 
    Contact m2 = new Contact(1, "name"); 
    m.put(m1, "first"); 
    m.put(m2, "second"); 
    System.out.println(m.get(m1));//first 
    System.out.println(m.get(m2));//second 
    System.out.println(m.get(new Contact(1, "name"));//null - since the new object has a different object reference. 
    
    0

    m1とm2は同じ値を持っていますが、それらは異なるオブジェクト参照です。

    これが正しい:オブジェクトm1とは を別の値が含まれているm2は場合JVMが参照するために方法はありませんので、 にはhashCodeメソッドはありません - >それはハッシュコード値を計算するためにObjectクラスのhasCode()メソッドを使用していますのでget()を実行して、異なるハッシュ値(明白)を返します。

    第二の点でも正しいです: あなた自身のequalsを(実装していないとして)、一つのオブジェクトが自身と比較されるだけを返す)(オブジェクトの等号を検討します。

    2

    オブジェクトクラスのequalsおよびhashcodeメソッドを使用して値を検索します(Contactはequalsおよびhashcodeメソッドをオーバーライドしないため)。

    1. はい、Javaは常にそれがオブジェクト
    2. にequalsメソッドを使用するときに、2つの連絡先オブジェクトが参照に持っているとして、それは、はい比較するためのオブジェクト参照を使用するように2つの連絡先オブジェクトが異なっているが表示されます。
    3

    すべてのオブジェクトにはhashCode()とequals()があります。それらがオーバーライドされていないときは、デフォルトの実装が使用されます。デフォルトの動作は、すべてのオブジェクトを同じオブジェクトでない限り異なるものとして扱うことです。

    IdentityHashMapは、hashCodeとequalsをオーバーライドしても常にこれを行います。

    0

    デフォルトでは、オブジェクトクラスはhashCodeとequalsメソッドをオーバーライドします。これが目的の出力を得る理由です。

    equalsメソッドとhashcodeメソッドをオーバーライドしないと、JVMはシーンの背後でそれをチェックします。 m1とm2はどちらも異なるオブジェクトインスタンスなので、equalsメソッドは常にfalseを返します。 すなわち:等号の場合

    1:両方が別のインスタンスであるため、

    m1.equals(M2)はfalseを返す//。ハッシュコードのために

    2: // HashMapのは、内部でハッシュマップに入れる前に鍵を焼き直しに使用するHashMap.java

    内のソースコードを参照してください。下記をご覧ください。焼き直しのための

    [![Source code of put method][1]][1] 
    public V put(K key, V value) { 
        return putVal(hash(key), key, value, false, true); 
    } 
    

    、HashMapのは、それが自分の静的ハッシュ方式のしている:あなたはHashMapの中に格納された値の両方を取得し、なぜ内部

    [![Source code of hash method][1]][1] 
    static final int hash(Object key) { 
         int h; 
         return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
        } 
    

    、このように両方のequalsとhashCodeメソッドの仕事を、それがあります。

    希望します。

    関連する問題