İlk olarak söylenmesi gereken şey “equals()” metodu ile “==” metodunun aynı şeyler olmadığı. “==” metodu referansların aynı nesneye işaret edip etmediğini karşılaştırır. Aslında “equals()” metodu da temelde aynı işlevi görür fakat “==” metodundan daha üstün donanıma sahip olarak geliştirebilir.
Java'nın Object sınıfına aittir ve aynı sınıfa ait “hashCode()” methodu ile doğrudan alakalıdır. “equals()” methodu dört önemli özelliğe sahiptir.
Reflexive: Bir “x” referansı verilfdiğinde x.equals(x) doğru(true) dönmelidir.
Symmetric: Verilen “x” ve “y” referansları için; x.equals(y)'nin doğru dönmesi için y.equals(x) dogru olmalıdır.
Transitive: Verilen “x”, “y” ve “z” referansları için, x.equals(y) true ve y.equlas(z) true dönüyorsa, x.equals(z)'de true döner.
Consistent : Verilen referansların eşilği, referanslar değiştirilmedikçe aynı kalmalı. Diğer bir değişle x.equlas(y) true dönüyorsa, ya “x” ya “y” yada iki referans birden değişmeden metot yeniden uygulandığında dönen değer yine true olmalıdır.
Bunların yanı sıra önemli olan iki özellik daha vardır. Eğer bir “x” referansı boş(null) bir referans ile karşılaştırılacaksa metot false dönmelidir. İkinci özellik ise eğer verilen iki nesne eşit ise(Örnek: x.equals(y) true dönüyorsa) ikisininde hash kodu aynı olmalıdır. Bu açıdan equals() ve hashCode() metotları birbiri ile bağlantılıdır. Bu sebeple eğer ki metotlardan biri farklı bir amaç için yeniden yazılacaksa diğeri de gözden geçirilmelidir.
Yukarıda bahsedilenler Object sınıfına ait olan equals() metoduna ait özelliklerdi. Kendi equals() metodunuzu yazacağınız zaman yukarıda belirtilen özelliklere bağlı kalmanız gerektiği gibi dikkat edilmesi geren birkaç nokta daha var. Bunları madde madde açıklamak daha sağlıklı olur.
Öncelikle, verilen değişkenin o nesneye işaret edip etmediğini kontrol etmek amacıyla “==” metodunun uygulanması. Eğer işaret ediyorsa true dönmeli.
Nesnenin boş(null) olup olmadığı kontrol edilmeli.
Verilen nesnenin eşitlik metodunda kullanmak için uygunluğu test edilmeli. Metodun uygulanacağı referansların aynı sınıfa ait olup olmadığı,aynı sınıfa ait nesneler değillerde ait oldukları sınıfların yazılan “equals()” metodunu destekleyip desteklemediği kontrol edilmeli. Yukarıdaki kontrollerden geçerse true, geçemez ise false dönmeli.
“false” döndüğü takdirde, nesnelerin türlerini eşitlemek (type casting) gerekir. Burada eşitlemeden kasıt, aynı türe dahil etmek ya da metodu destekleyen sınıfların türüne değiştirmektir.
Örneğin,
x referansı int, y referansı float türünde olsun. Yazılan equals() metodu int türünü destekliyor ise y referansını int türüne çevirmek gerekir.
Sınıfa ait olan nesneyi (this.object) ve argümanın eşitliğini kontrol etmek gerekir. Eğer eşitlerse, true dönmelidir.
Yazdığınız “equals()” metodunun arguman türünü(type) değiştirmemelisiniz. Argüman olarak bir Object sınıfı nesnesi almalıdır. Eğer değiştirilirse, metodu üzerine yazmak(override) yerine, aşırı yüklemiş(overload) olursunuz. Derlerken herhangi bir hata ile karşılaşmazsınız ama, yazdığınız kodun doğru çalışmayacağını görürsünüz. Böyle olmasını sebebi ise şudur: sizin Java ile yazacağınız her hangi yeni bir sınıf zaten Object sınıfından miras alır. Yani aslında sizin kendi sınıfınıza ait yarattığınız bir nesne aynı zamanda Object sınıfına ait bir nesne gibi davranabilir. Bu sebeple argüman türünü değiştirmeniz gerekmez.
Yazdığınız equals() metodunun tüm gereklilikleri yerine getirip getirmediğini kontrol ettikten sonra hash kodunu değiştirmelisiniz.
Not: Yazdığınız kodu başka kullanıcıların anlaması için açıklama (comment) koymayı unutmazsanız iyi olur. :)
Kısaca özetlersek,
“equal” olan nesnelerin hash kodları aynı olmalıdır.
“deep comparison” (derin karşılaştırma :) ) yapmalıdır.
Boş (null) bir parametre ile karşılaştırıldığında false dönmelidir.
Yukarıda bahsedilen dört önemli özelliğe (symmetric, reflexive, transitive, consistent) sahip olmalıdır.
Not: Bir sonraki girdim de yazılan bir equals() metodunun nasıl test edileceğinden bahsedeceğim. :)
Tags: Programlama dilleri