CodeGym /Java Blogu /Rastgele /Java hashCode()
John Squirrels
Seviye
San Francisco

Java hashCode()

grupta yayınlandı

Hash İlkesi

Ö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.

import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    } 

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
Programı çalıştırmanın sonucu:

Arnold
1595428806
Arnold
1072408673
false
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: Java hashCode() nedir - 2

import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Character)) return false;

        Character character = (Character) o;

        return getName() != null ? getName().equals(character.getName()) : character.getName() == null;
    }

    @Override
    public int hashCode() {
        return getName() != null ? getName().hashCode() : 0;
    }

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
Bu kodu çalıştırmanın sonucu:

Arnold
1969563338
Arnold
1969563338
true
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 :

import java.util.Date;

public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(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
   @Override
   public int hashCode(){
       //TODO: check for nulls
       //return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(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:

import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;

public class Main {
   static HashMap<Student, Integer> cache = new HashMap<Student, Integer>(); // <person, targetPriority>

   public static void main(String[] args) {
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student sarah2 = new Student("Sarah","Connor", "Jane", new Date(1970, 01-1, 01));
       Student sarah3 = new Student("Sarah","Connor", "Jane", new Date(1959, 02-1, 28)); // date not exists
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       Student johnny = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       System.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(new Date(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.
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION