equals() ve hashCode()
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 42 / 87.
Java'da nesneleri karşılaştırırken, == operatörü iki referansın aynı bellek konumunu gösterip göstermediğini kontrol eder. Nesnelerin gerçek içeriğini karşılaştırmak için equals() metodunu geçersiz kılmanız (override etmeniz) gerekir.
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}equals() yöntemi standart bir kalıbı takip eder: önce aynı nesne olup olmadığını kontrol edin, ardından türü doğrulayın ve son olarak ilgili alanları karşılaştırın.
Ne zaman equals() metodunu geçersiz kılarsanız, hashCode() metodunu da geçersiz kılmalısınız. Bu, Java'da bir sözleşmedir: eşit olan nesneler aynı hash koduna sahip olmalıdır. HashMap ve HashSet gibi hash tabanlı koleksiyonlar, doğru çalışmak için bu kurala dayanır.
@Override
public int hashCode() {
return Objects.hash(name, age);
}Objects.hash() yardımcı yöntemi, equals() içinde kullanılan alanların aynısından bir karma kod oluşturur. Eğer iki Person nesnesi aynı isme ve yaşa sahipse, eşit kabul edilecekler ve özdeş karma kodlar üreteceklerdir; bu da koleksiyonlarda tutarlı bir davranış sağlar.
Görev
KolayNesne eşitliğini düzgün bir şekilde uygulayan bir öğrenci kayıt sistemi oluşturalım. Bellekte aynı nesne olup olmadıklarına bakılmaksızın, aynı öğrenci kimliğine ve ismine sahip iki öğrencinin eşit kabul edildiği bir Student sınıfı oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
Student.java: Üç özel (private) alana sahip bir öğrenciyi temsil eden bir sınıf oluşturun:studentId(String),name(String) vegpa(double). Tüm alanları başlatan bir yapıcı (constructor) ve her alan için getter metotları ekleyin.equals()metodunu, iki Student nesnesinin aynıstudentIdVE aynınamedeğerine sahip olduklarında eşit kabul edilecek şekilde geçersiz kılın (override). Standart kalıbı izleyin: aynı referansı kontrol edin, null ve tür kontrolü yapın, ardından ilgili alanları karşılaştırın.hashCode()metodunu,equals()içinde kullanılan aynı alanlarlaObjects.hash()kullanarak geçersiz kılın (override). Dosyanızın en üstünejava.util.Objectsiçe aktarmayı (import) unutmayın.Main.java: Öğrenci nesnelerini karşılaştırarak Student sınıfınızı hayata geçirin. İki öğrenciyi temsil eden altı girdi alacaksınız: birinci öğrencinin kimliği, ismi ve GPA'sı, ardından ikinci öğrencinin kimliği, ismi ve GPA'sı.Her iki Student nesnesini de oluşturun, ardından üç karşılaştırma yapın ve sonuçları yazdırın:
Same reference:ifadesini ve ardından birinci öğrencinin kendisine eşit olup olmadığını yazdırın (her zaman true olmalıdır)Content equality:ifadesini ve ardından birinci öğrencinin ikinci öğrenciye eşit olup olmadığını yazdırın (equals uygulamanıza bağlı olarak)Hash codes match:ifadesini ve ardından her iki öğrencinin de aynı hash koduna sahip olup olmadığını yazdırın
Altı girdi alacaksınız: birinci öğrencinin kimliği (String), birinci öğrencinin ismi (String), birinci öğrencinin GPA'sı (double), ikinci öğrencinin kimliği (String), ikinci öğrencinin ismi (String) ve ikinci öğrencinin GPA'sı (double).
İki öğrencinin eşleşen kimlikleri ve isimleri olduğunda, hem equals() metodunun true döndürdüğüne HEM DE hash kodlarının eşleştiğine dikkat edin—bu, sürdürmeniz gereken sözleşmedir!
Kopya kağıdı
== operatörü, nesnelerin aynı içeriğe sahip olup olmadığını değil, iki referansın aynı bellek konumunu gösterip göstermediğini kontrol eder.
Nesne içeriğini karşılaştırmak için, şu deseni izleyerek equals() metodunu geçersiz kılın:
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Aynı referans
if (obj == null || getClass() != obj.getClass()) return false; // Null veya farklı tür
Person person = (Person) obj; // Doğru türe dönüştür
return age == person.age && name.equals(person.name); // Alanları karşılaştır
}equals() metodunu her geçersiz kıldığınızda, hashCode() metodunu da geçersiz kılmalısınız. Bu bir Java sözleşmesidir: eşit nesneler aynı hash koduna sahip olmalıdır.
@Override
public int hashCode() {
return Objects.hash(name, age);
}equals() içinde kullanılan alanların aynısıyla Objects.hash() kullanın. Bu, HashMap ve HashSet gibi hash tabanlı koleksiyonların doğru çalışmasını sağlar.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// İlk öğrencinin verilerini oku
String id1 = scanner.nextLine();
String name1 = scanner.nextLine();
double gpa1 = scanner.nextDouble();
scanner.nextLine(); // yeni satırı tüket
// İkinci öğrencinin verilerini oku
String id2 = scanner.nextLine();
String name2 = scanner.nextLine();
double gpa2 = scanner.nextDouble();
// TODO: Giriş verilerini kullanarak iki Student nesnesi oluşturun
// TODO: "Same reference: " ve ardından student1'in kendisine eşit olup olmadığını yazdırın
// TODO: "Content equality: " ve ardından student1'in student2'ye eşit olup olmadığını yazdırın
// TODO: "Hash codes match: " ve ardından her iki öğrencinin aynı hash koduna sahip olup olmadığını yazdırın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı