2011-07-29 19 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)); 
    } 
} 

Çıktı geçerli:HashCode olmadan Harita tuşları olarak Nesneler ve eşit

first 
second 

Bu nasıl "get" yöntemi davranıyor? Hem m1 hem de M2'nin aynı değerleri olduğu ve hashcode() 'ı geçersiz kılmadığım için Object sınıfının equals() yöntemi çağrılacak mı?

Bu doğru mu?

  • Orada hiçbir yöntem bu yüzden sınıfının eşittir (Nesne geçersiz) çağrılır eşittir ve nesneler m1 ve m2 farklı değerler içeriyorsa JVM görmek için bir yolu yoktur bu yüzden

    1. hiçbir karma kodudur yöntemi yoktur hem nesneler olarak Yukarıdaki kod, m2 değerinin m1 değerini değiştirmeksizin iyi çalışıyor.
  • cevap

    8

    Java sadece değerlerini hesaplamak için bellekte nesnesine gerçek referansı kullanır (yani. O sınıfın aynı instantiation olup olmadığını kontrol edin). Bu yüzden hala iki sonuç elde edersiniz.

    0

    İşte Contact sınıfta Eğer hashcode() ve equals() işlevleri yerine vermedi.

    HashMap bu yöntemi çağırdığında, bu durumda Nesne olan üst sınıftaki bu yöntem için arama yapar.

    Bu durumda Yığındaki nesne konumu değerler yerine değerlendirilir.

    örn. İki nesne o1 ve o2

    o1.equals(o2) == true için sadece o1 == o2

    hashCode() nesne sınıfının bir metodu olduğunda. Karma kod, JVM tarafından bir nesnenin tam sayı gösterimidir. Karma kod, sistem oluşturulur ve JVM, karma kodunu oluşturmak için nesnenin adresini temel (tohum) olarak alır. Oluşturulan karma kodların farklı yürütme süreleri için aynı olması gerekmez.

    0

    Evet, bu doğru. Kendi eşittir ve hata kodu yöntemlerini tanımlamayan herhangi bir java nesnesi, java.lang.Object öğesinde varsayılan eşittir ve kodlama yöntemlerini devralır. Bu varsayılan uygulama, mantıksal eşitlikte değil, nesne referansı eşitliğine dayanır. Aynı nesne referansı ile arama yaptığınız için, nesne haritadan döndürülebilir.

    Bu, daha fazla hata yapan bir örnektir. hashCode() ve equals(Object o) yöntemleri sınıfı tarafından geçersiz değildir

    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 ve m2 aynı değerlere sahip olsa da, farklı nesne referanslarıdır.

    Bu doğrudur: nesneleri m1 ve farklı değerleri içeren m2 eğer JVM görmek için bir yolu yoktur bu yüzden hiçbir karma kodudur yöntemi yoktur -> o hashCode değerini hesaplamak için Nesne sınıfının hasCode() yöntemini kullanır Yani Farklı karma değerleri (açık) döndüren get() öğesini çalıştırmak için

    ikinci nokta

    da doğrudur: Eğer() bir nesne kendisine karşılaştırılır sadece gerçek döndürür Nesnenin eşittir dikkate alacaktır kendi equals(), uygulamayan gibi.

    2

    (İletişim eşittir ve karma kodudur yöntemlerini overide gelmez gibi) Bu değeri bulmak için eşittir ve nesne sınıfının karma kodudur yöntemini kullanır, bu yüzden evet. o referanslarına iki kontak nesneler olarak, nesne

  • Evet de eşittir yöntemi var kullanırken karşılaştırmak için nesne başvurusu kullanacak şekilde
    1. Evet, Java hep göreceksiniz iki İletişim nesneleri farklıdır.
  • 3

    Tüm Nesneler hashCode() ve equals var(). Geçersiz kılınmadıklarında, varsayılan uygulamalar kullanılır. Varsayılan davranış, aynı nesne olmadıkça, tüm nesneleri farklı olarak ele almaktır.

    Karşılaştırma için, IdentityHashMap her zaman size hashCode geçersiz ve eşit olsa bile bunu yapar. Varsayılan Object sınıfı tarafından

    0

    hashCode geçersiz kılmak ve yöntemi eşittir. İstediğiniz çıktıyı almanızın nedeni budur. Eğer eşittir ve karma kodudur yöntemini geçersiz yoksa

    , JVM sahnesi geride denetler. M1 ve m2'nin her ikisi de farklı nesne örnekleri olduğundan, eşittir yöntemi her zaman yanlıştır. yani: eşitleri için

    1.: Her iki farklı örnekleri çünkü

    m1.equals (m2) return false //. hashCode için

    2.: //

    HashMap içten HashMap koymadan önce anahtarı yeniden karıştıracak kullandığı HashMap.java iç kaynak koduna bakın. Gördün mü?

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

    , HashMap kendi statik karma yöntemidir vardır: Her iki değerler HashMap depolanır neden

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

    Dahili olarak, bu şekilde hem equals ve hashCode yöntemi işi, yani .

    Umut bu yardımcı olur :)

    İlgili konular