Merhaba,

Bugün Object sınıfına ait GetHashCode metodu ile ilgili bilgi vermek istiyorum. Bu metodun tanımları :


//Delphi:
function GetHashCode(): Integer; overload; virtual;

//C++:
public: virtual int GetHashCode();

Objenin hash kodunu döndürür ki bu da objeye karşılık gelen sayısal bir değerdir ve hash tablosu mantığında objeye erişimi hızlandırmak amacıyla böyle sayısal değerler kullanılır.

GetHashCode fonksiyonunun mevcut hali, her bir obje için farklı değerler döndürmeyi garantilemez. Farklı sınıflara ait objeler mutlaka farklı hash kodlara sahiptirler, ama aynı sınıfa ait farklı nesneler aynı hash kodu taşıyor olabilirler. Yani hash kodu farklı iki nesne farklıdır ama bunun tersi doğru değildir. Bu yüzden eğer eşitlik karşılaştırması için kullanılacaksa bu metot, sizin sınıf yapınızda ezilmiş olmalıdır.


Ayrıca mevcut haliyle GetHashCode fonksiyonu, objenin içeriği değiştikçe farklı farklı değerler döndürüyor ve mesela içini boşalttığımız bir objenin hash kodu farklı dönerken, daha önce verdiğimiz bir değerin aynısını verirsek yine aynı hash kod dönüyor. Farklı objelerde de bu aynı şekilde oluyor, yani bu durumda her değer tek bir hash koda sahipmiş gibi sanki. Dolayısıyla aynı içeriğe sahip iki farklı obje aynı hash kodu döndürüyor. Şimdi aşağıdaki kodda bunu görelim (hash kod değerleri satır sonundadır) :


var
  obj1 : &Object;
  obj2 : &Object;
begin
  obj1 := &Object.Create;
  obj2 := &Object.Create;
  ShowMessage('code1 : '+inttostr(obj1.GetHashCode));	//code1 : 18
  ShowMessage('code2 : '+inttostr(obj2.GetHashCode));	//code2 : 23
  obj1 := 'aa';
  obj2 := 'ab';
  ShowMessage('code1 : '+inttostr(obj1.GetHashCode));	//code1 : 5860901
  ShowMessage('code2 : '+inttostr(obj2.GetHashCode));	//code2 : 5860902
  obj2 := obj1;
  ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); 	//code1 : 5860901
  ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); 	//code2 : 5860901
  obj1 := NULL;
  obj2 := NULL;
  ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); 	//code1 : 39
  ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); 	//code2 : 39
  obj1 := 'ab';
  obj2 := 'aa';
  ShowMessage('code1 : '+inttostr(obj1.GetHashCode)); 	//code1 : 5860902
  ShowMessage('code2 : '+inttostr(obj2.GetHashCode)); 	//code2 : 5860901
end;

Bu haliyle fonksiyonumuz çok kullanışlı sayılmaz değil mi..

Aşağıda da klasik bir sınıf-öğrenci örneği için GetHashCode fonksiyonun ezilmiş hali var. Burada iki objenin eşit olabilmesi için hem sınıf hem de numara değerlerinin aynı olması gerekir. Dolayısıyla sadece sınıf bazında numaraların tekliğinin sağlanmış olması yeterlidir.


TMyClass = class(System.&Object)
public
    adi    : string;
    soyadi : string;
    numara : integer;
    sinif  : integer;
    Function GetHashCode : integer; override;
end;

Function TMyClass.GetHashCode : integer;
begin
   Result := strtoint(inttostr(sinif)+inttostr(numara));
end;

var
  a1 : TMyClass;
  a2 : TMyClass;
begin
  a1 := TMyClass.Create;
  a2 := TMyClass.Create;
  a1.adi := 'Ali';
  a1.numara := 15;
  a1.sinif := 2;
  a2.adi := 'Veli';
  a2.numara := 15;
  a2.sinif := 3;
  ShowMessage('code1 : '+inttostr(a1.GetHashCode));
  ShowMessage('code2 : '+inttostr(a2.GetHashCode));

  if (a1.GetHashCode = a2.GetHashCode) then
    ShowMessage('eşit!!');
end;

Bu arada Tuğrul’a da teşekkür etmek istiyorum. Bana kalsa hep erteleyip duracaktım bu dotNET öğrenme işini. Hepimizin böyle motivasyonlara ihtiyacı var silkinip harekete geçmek için galiba. Ama bundan fayda görecek ya da göremeyecek olan da sadece biziz aslında…

İyi çalışmalar

Nihal Pehlivan

One Response to “Object.GetHashCode metodu”
  1. özkan danacı says:

    güzel bir makale olmuş öncelikle:
    ben pek fazla hakim değilim oop konularına
    sınıfların eşitliklerini ancak bu şekilde mi kontrol edebiliriz.
    yani;
    –if (sınıf_1=sınıf_2)– şeklinde kullanım olmaz mı?

    illaki –if (sınıf_1.GetHashCode=sınıf_2.GetHashCode)– şeklinde mi olmalı.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>