ProgramlamaJava Geliştirici

Java'da hashCode() yönteminin yeniden tanımlanma mekanizması nasıl çalışır, bu süreçte hangi kurallara uyulmalıdır ve bu kuralların ihlali hangi kritik hatalara yol açabilir?

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

Cevap.

hashCode() yönteminin yeniden tanımlanması, equals() yönteminin yeniden tanımlanması ile yakından bağlantılıdır: her iki yöntem de HashMap, HashSet, Hashtable ve diğer karşılaştırma ve hash fonksiyonlarına dayanan koleksiyonlarda nesnenin doğru bir şekilde kullanılabilmesi için temel oluşturur.

Kurallar:

  • Eğer equals() yöntemini yeniden tanımlıyorsanız, mutlaka hashCode() yöntemini de yeniden tanımlayın.
  • equals() ile eşit olan nesneler aynı hashCode() değerini döndürmelidir.
  • Hata önlemek için, hash oluşturmanın standart yollarını kullanmanız önerilir, örneğin Objects.hash() veya IDE şablonları.
  • hashCode() aynı nesne için ömrü boyunca aynı değeri döndürmelidir (eğer hashCode'da yer alan alanlar değişmezse).
class User { private String name; public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User user = (User) o; return Objects.equals(name, user.name); } public int hashCode() { return Objects.hash(name); } }

Kandırmaca Soru.

Soru: "Eğer equals() ile farklı olan iki nesne aynı hashCode() değerini dönerse ne olur? Bu bir hata mı?"

Cevap: Hayır, bu bir hata değildir. Hash kodu çakışmaları kabul edilebilir ve beklenmediktir - önemli olan, eğer nesneler equals ile eşitse, hashCode değerlerinin aynı olmasıdır. Eğer equals ile farklı nesneler aynı hashCode değerini verirse, koleksiyonlar daha yavaş çalışacaktır (daha fazla çakışma nedeniyle), fakat düzgün bir şekilde çalışacaktır.

Bu konuda bilgi eksikliğinden kaynaklanan gerçek hata örnekleri.


Hikaye

Finansal yazılımda projeleri birkaç alan üzerinden karşılaştırdılar, ama sadece equals() yöntemini yeniden tanımladılar. Nesneleri HashSet içinde sakladılar, çünkü hashCode() yeniden tanımlanmadığı için varsayılan olarak çalışıyordu (her örneği için farklıydı).


Hikaye

Depo yönetim sisteminde iş mantığı değişiklikleri yapıldıktan sonra equals() genişletildi, ama hashCode() güncellenmeyi unuttu. Farklı hashCode'a sahip ama equals=true olan nesneler HashMap içinde kayboldu (anahtar ile bulunamadı), büyük finansal hatalara yol açtı.


Hikaye

Web uygulamasında hashCode hesaplamasında değişken alanlar kullanıldı. İç alanın değeri güncellendiğinde hash değişiyordu ve nesne HashSet/HashMap için "kayboluyordu": standart yöntemlerle bulunamıyor ya da silinemiyordu, bu da bellek sızıntılarına ve hatalara yol açıyordu.