ProgramlamaJava geliştirici

Java'daki equals() metodunun özelliklerini açıklayın: ne zaman ve neden yeniden yazılmalı, nasıl doğru bir şekilde uygulanmalı ve yanlış kullanımda hangi sorunlar ortaya çıkabilir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

equals() metodu, iki nesnenin "eşit" olup olmadığını tanımlar. Varsayılan olarak, referansları karşılaştırır (yani ==), ancak sık sık sınıfların (örneğin, varlıklar, değer nesneleri) veriler üzerinde mantıksal karşılaştırma gerektirir.

Ne zaman yeniden yazılmalı:

  • Sınıfınız için nesnelerin mantıksal kimliği önemliyse (örneğin, aynı e-posta adresine sahip iki kullanıcı "aynı kullanıcıdır")
  • Nesne koleksiyonlarda saklanacaksa (örneğin, HashSet), bu da equals (ve hashCode) kullanır.

Gereklilikler:

  • Equals, yansıtıcı, simetrik, geçişli, tutarlı olmalı ve herhangi bir null olmayan x için, x.equals(null) false olmalıdır.
  • Equals'ı yeniden yazarken, hashCode'u da İNANILMAZ bir şekilde yeniden yazmalısınız!

Örnek:

public class Person { private String email; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(email, person.email); } @Override public int hashCode() { return Objects.hash(email); } }

Kandırma Sorusu

Eğer iki nesne equals() ile eşitse, hashCode() her zaman aynı mı olmalıdır?

Cevap: Evet! Bu, Java'nın sözleşimlerindeki bir gerekliliktir. Ancak tam tersi yanlıştır: Aynı hashCode'a sahip iki nesne equals() ile eşit olmayabilir — hash kodları farklı nesneler için çakışabilir (çakışmalar).

Hata örneği:

person1.equals(person2); // true person1.hashCode() != person2.hashCode(); // Hata!

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri


Hikaye

Kurumsal bir uygulamada Kullanıcı varlığı bir HashSet'e eklendi. Equals yeniden yazılmış, hashCode — yazılmamıştı. Equals'ı etkileyen alanların değiştirilmesinden sonra, HashSet bu nesneyi "kaybetti": contains metodu aynı veriler için false döndürdü.


Hikaye

IoT projesinde, varlıklar geçici olarak yalnızca id ile karşılaştırıldı, ardından mantık, ismi dikkate alacak şekilde equals'a değiştirildi. HashMap tahmin edilemez bir şekilde davrandı, anahtarlar güncellenirken kopyalar oluştu — equals/hashCode sözleşmesi, uygulama sürümlerinin karıştırılması nedeniyle ihlal edildi.


Hikaye

Siparişleri karşılaştırmak için API yazarken, iki farklı sınıf kendi equals yöntemini uygular; bunlardan biri getClass() çağırırken, diğeri instanceof kullanıyordu. Bu, siparişlerin asimetrik bir şekilde karşılaştırılmasına ve koleksiyonlar ile iş mantığında hatalara yol açtı.