Öncelikle Java hashcode'u tanımlamadan önce hash nedir ve ne işe yarar onu anlamamız gerekir. Hashing, bazı verilere bir hash işlevi uygulama işlemidir. Hash fonksiyonu sadece matematiksel bir fonksiyondur. Bunun için endişelenme! "Matematiksel" her zaman "karmaşık" anlamına gelmez. Burada sadece bazı verilere ve verileri bir dizi karaktere (kod) eşleyen belirli bir kurala sahip olduğumuz anlamına gelir. Örneğin, onaltılık bir şifre olabilir. Girdide herhangi bir boyutta bazı verilerimiz var ve bunlara bir hash işlevi uyguluyoruz. Çıktıda, örneğin 32 karakter gibi sabit boyutlu bir veri alıyoruz. Genellikle, bu tür bir işlev, büyük bir veri parçasını küçük bir tamsayı değerine dönüştürür. Bu işlev çalışmasının sonucu bir hash kodu olarak adlandırılır. Karma işlevler, kriptografide ve diğer bazı alanlarda da yaygın olarak kullanılmaktadır. Hash fonksiyonları farklı olabilir,
Belirli bir nesnenin belirli bir karma kodu vardır.
İki nesne eşitse, hash kodları da aynıdır. Tersi doğru değil.
Hash kodları farklıysa, nesneler kesinlikle eşit değildir.
Farklı nesneler aynı hash koduna sahip olabilir. Ancak bu pek olası olmayan bir olaydır. Bu noktada bir çakışma, veri kaybedebileceğimiz bir durum var.
"Uygun" hash işlevi, çarpışma olasılığını en aza indirir.
Java'da hash kodu
Java'da hash işlevi genellikle hashCode() yöntemine bağlıdır . Kesin olarak, bir Nesneye bir karma işlevi uygulamanın sonucu bir karma kodudur. Her Java nesnesinin bir karma kodu vardır. Genel olarak Hash Kodu, sınıfın hashCode() yöntemi tarafından hesaplanan bir sayıdır Object. Genellikle, programcılar bu yöntemi nesnelerinin yanı sıra belirli verilerin daha verimli işlenmesi için hashCode() ile ilgili equals () yöntemini geçersiz kılar. hashCode () yöntemi, nesnenin sayısal bir temsili olan bir int (4 bayt) değeri döndürür. Bu hashcode, örneğin koleksiyonlar tarafından verilerin daha verimli depolanması ve dolayısıyla bunlara daha hızlı erişim için kullanılır. Varsayılan olarak, hashCode()bir nesne için işlev, nesnenin depolandığı bellek hücresinin numarasını döndürür. Bu nedenle, uygulama kodunda herhangi bir değişiklik yapılmadıysa, işlev aynı değeri döndürmelidir. Kod biraz değişirse, hashcode değeri de değişir. Java'da kullanılan karma kod nedir? Her şeyden önce, Java karma kodları programların daha hızlı çalışmasına yardımcı olur. o1Örneğin, iki nesneyi ve herhangi bir türü karşılaştırırsak o2, işlem o1.equals(o2)yaklaşık 20 kat daha fazla zaman alır o1.hashCode() == o2.hashCode().
Java eşittir ()
Üst sınıfta , hashCode()Object yönteminin yanı sıra , iki nesnenin eşitliğini kontrol etmek için kullanılan equals() işlevi de vardır . Bu işlevin varsayılan uygulaması, iki nesnenin bağlantılarını eşdeğerlik açısından kontrol eder. equals() ve hashCode()' un kendi sözleşmeleri vardır, dolayısıyla birini geçersiz kılarsanız, bu sözleşmeyi bozmamak için diğerini geçersiz kılmalısınız.
hashCode() yöntemini uygulama
Örnek
Tek bir alana sahip bir Karakter sınıfı oluşturalım - name . Bundan sonra, Karakter sınıfından, karakter1 ve karakter2 olmak üzere iki nesne yaratıyoruz ve onlara aynı adı veriyoruz. Object sınıfının varsayılan hashCode() ve equals() öğelerini kullanırsak , eşit değil, kesinlikle farklı nesneler elde ederiz. Java'da hashcode böyle çalışır. Farklı bellek hücrelerinde oldukları için farklı hash kodlarına sahip olacaklar ve equals() işleminin sonucu yanlış olacaktır.
Konsoldaki iki adet 10 haneli sayı karma kodlardır. Aynı ada sahiplerse eşit nesnelere sahip olmak istersek ne olur? Ne yapmalıyız? Cevap: Karakter sınıfımız için Object sınıfının hashCode() ve equals() yöntemlerini geçersiz kılmalıyız . Bunu IDEA IDE'de otomatik olarak yapabiliriz, sadece klavyenizde alt + insert tuşlarına basın ve Generate -> equals() ve hashCode() öğelerini seçin . Örneğimizde, bir sonraki kodumuz var:
Böylece program, nesnelerimizi eşit olarak tanımlar ve aynı karma kodlara sahiptirler.
Java karma kodu örneği:
Kendi hashCode() ve eşittir()
Kendi equals() ve hashCode() gerçekleştirmelerinizi de oluşturabilirsiniz , ancak dikkatli olun ve karma kod çarpışmalarını en aza indirmeyi unutmayın. İşte Student sınıfındaki kendi hashCode() ve equals() yöntemlerimize bir örnek :
importjava.util.Date;publicclassStudent{String surname;String name;String secondName;Long birthday;// Long instead of long is used by Gson/Jackson json parsers and various orm databasespublicStudent(String surname,String name,String secondName,Date birthday ){this.surname = surname;this.name = name;this.secondName = secondName;this.birthday = birthday ==null?0: birthday.getTime();}//Java hashcode example@OverridepublicinthashCode(){//TODO: check for nulls//return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());return(surname + name + secondName + birthday).hashCode();}@Overridepublicbooleanequals(Object other_){Student other =(Student)other_;return(surname ==null|| surname.equals(other.surname))&&(name ==null|| name.equals(other.name))&&(secondName ==null|| secondName.equals(other.secondName))&&(birthday ==null|| birthday.equals(other.birthday));}}
Ve çalışmalarını göstermek için Ana sınıf:
importjava.util.Date;importjava.util.HashMap;importjava.util.Hashtable;publicclassMain{staticHashMap<Student,Integer> cache =newHashMap<Student,Integer>();// <person, targetPriority>publicstaticvoidmain(String[] args){Student sarah1 =newStudent("Sarah","Connor","Jane",null);Student sarah2 =newStudent("Sarah","Connor","Jane",newDate(1970,01-1,01));Student sarah3 =newStudent("Sarah","Connor","Jane",newDate(1959,02-1,28));// date not existsStudent john =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsStudent johnny =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsSystem.out.println(john.hashCode());System.out.println(johnny.hashCode());System.out.println(sarah1.hashCode());System.out.println();
cache.put(sarah1,1);
cache.put(sarah2,2);
cache.put(sarah3,3);System.out.println(newDate(sarah1.birthday));System.out.println();
cache.put(john,5);System.out.println(cache.get(john));System.out.println(cache.get(johnny));
cache.put(johnny,7);System.out.println(cache.get(john));System.out.println(cache.get(johnny));}}
Hashcode ne için kullanılır?
Her şeyden önce, karma kodlar programların daha hızlı çalışmasına yardımcı olur. o1Örneğin, iki nesneyi ve bir türü karşılaştırırsak o2, işlem o1.equals(o2)o1.hashCode() == o2.hashCode() işleminden yaklaşık 20 kat daha fazla zaman alır. Java'da karma ilkesi, HashMap , HashSet ve HashTable gibi bazı popüler koleksiyonların arkasında durur .
Çözüm
Her Java nesnesi, Object sınıfından miras alınan hashCode() ve equals() yöntemlerine sahiptir . İyi çalışan bir eşitlik mekanizması elde etmek için kendi sınıflarınız için hashcode() ve equals() yöntemlerini geçersiz kılmanız daha iyi olur . Karma kodları kullanmak, programların daha hızlı çalışmasını sağlar.