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:
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.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); } }
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.
Hikaye
Finansal yazılımda projeleri birkaç alan üzerinden karşılaştırdılar, ama sadece
equals()yöntemini yeniden tanımladılar. NesneleriHashSetiç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, amahashCode()güncellenmeyi unuttu. FarklıhashCode'a sahip amaequals=trueolan nesnelerHashMapiçinde kayboldu (anahtar ile bulunamadı), büyük finansal hatalara yol açtı.
Hikaye
Web uygulamasında
hashCodehesaplamasında değişken alanlar kullanıldı. İç alanın değeri güncellendiğinde hash değişiyordu ve nesneHashSet/HashMapiçin "kayboluyordu": standart yöntemlerle bulunamıyor ya da silinemiyordu, bu da bellek sızıntılarına ve hatalara yol açıyordu.