Java'da equals() ve hashCode() sözleşmesi nedir? Neden ikisini birlikte override etmek gerekir?

Cevap

Sözleşme şudur: `a.equals(b)` true ise `a.hashCode() == b.hashCode()` olmak zorundadır. Tersi gerekmez; farklı nesnelerin hash'i çakışabilir (collision).

HashMap, HashSet gibi yapılar önce hashCode() ile bucket'ı bulur, sonra o bucket içinde equals() ile karşılaştırır. Sadece equals()'ı override edip hashCode()'u bırakırsanız, "eşit" iki nesne farklı bucket'lara düşer ve set içinde iki kez görünür, map.get() null döner.

public final class Email {
    private final String value;
    public Email(String value) { this.value = value.toLowerCase(); }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Email other)) return false;
        return value.equals(other.value);
    }

    @Override
    public int hashCode() { return value.hashCode(); }
}

Java 16+ ile record Email(String value) {} yazarsanız equals, hashCode ve toString otomatik ve doğru üretilir.

equals() kuralları

  • Reflexive: x.equals(x) true
  • Symmetric: x.equals(y) ise y.equals(x)
  • Transitive, consistent ve x.equals(null) her zaman false

Tuzak: mutable key

Bir nesneyi HashMap'e key olarak koyduktan sonra hash'e giren alanını değiştirirseniz, nesne yanlış bucket'ta kalır ve artık bulunamaz. Key olarak immutable nesneler (String, record, Long) kullanın.

  1. Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?OrtaJava & SpringBackend
  2. ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?OrtaJava & SpringBackend
  3. JPA/Hibernate'te lazy ve eager loading farkı nedir? LazyInitializationException neden oluşur ve nasıl çözülür?OrtaJava & SpringBackend
  4. @Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.ZorJava & SpringBackend
  5. Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?KolayJava & SpringBackend
  6. Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?KolayJava & SpringBackend

Bu konuda başka bir soru biliyor musun?

Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.

Soru ekle