जेव्हा तुम्ही तार्किक समानता परिभाषित करण्यासाठी equals() ला override करता, तेव्हा तुम्ही ला override केले — कारण hash-आधारित संग्रह (, ) अशा करारावर अवलंबून असतात ज्यामध्ये . हा करार मोडणे सूक्ष्म आणि शोधण्यास कठीण असलेल्या बगस निर्माण करते.
जेव्हा तुम्ही तार्किक समानता परिभाषित करण्यासाठी equals() ला override करता, तेव्हा तुम्ही ला override केले — कारण hash-आधारित संग्रह (, ) अशा करारावर अवलंबून असतात ज्यामध्ये . हा करार मोडणे सूक्ष्म आणि शोधण्यास कठीण असलेल्या बगस निर्माण करते.
hashCode()HashMapHashSet// by default, equals() compares IDENTITY (same object?), hashCode() is based on memory address
Person p1 = new Person("Ann", 30);
Person p2 = new Person("Ann", 30);
p1.equals(p2); // false by default — different objects, even with same data
Override केल्याशिवाय, समान सामग्री असलेली दोन ऑब्जेक्ट्स "समान" नसतात — सामान्यतः value ऑब्जेक्ट्ससाठी हे इच्छित नसते.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person p = (Person) o;
return age == p.age && Objects.equals(name, p.name); // compare by CONTENT
}
@Override
public int hashCode() {
return Objects.hash(name, age); // MUST be consistent with equals()
}
करार: जर a.equals(b) true असेल, तर a.hashCode() == b.hashCode() अवश्य true असायला हवे.
Person p1 = new Person("Ann", 30);
Person p2 = new Person("Ann", 30); // equal by our equals()
Set<Person> set = new HashSet<>();
set.add(p1);
set.contains(p2); // ❌ likely FALSE — even though p1.equals(p2)!
केन? HashMap/HashSet प्रथम hashCode() वापरून योग्य बादली शोधतात, नंतर त्यामधील equals() वापरतात. डिफॉल्ट (identity-based) hashCode() सह, p1 आणि p2 भिन्न बादल्यांमध्ये जातात, तर contains त्यांची कधीच तुलना करत नाही — सेट समजते की ते भिन्न आहेत. यामुळे गोंधळलेल्या बगस निर्माण होतात: Set मधील डुप्लिकेट्स, नकारलेले map lookups इत्यादी.
1. equal objects → equal hash codes (REQUIRED for correctness)
2. unequal objects MAY have the same hash (collisions are allowed)
3. hashCode() must be consistent (same object → same code, unchanged)
4. equals() must be reflexive, symmetric, transitive, consistent
record Person(String name, int age) {} // records auto-generate equals/hashCode/toString!
Java records (आणि IDE generation / Lombok) तुमच्यासाठी योग्य, सुसंगत equals/hashCode तयार करतात.
equals/hashCode करार Java चा एक सर्वात महत्वाचा — आणि सर्वात सामान्यतः उल्लंघन केलेला — नियम आहे.
equals() ला hashCode() शिवाय override करणे hash-आधारित संग्रहांना प्रकारे तोडते जे debug करणे कठीण आहे: तुम्ही समान मानलेली ऑब्जेक्ट्स HashMap/HashSet मध्ये "हरली जातात" (नकारलेले lookups, भूतकथित डुप्लिकेट्स) कारण ते भिन्न बादल्यांमध्ये hash करतात.
चूक या संग्रह सर्वत्र आहेत, key किंवा set element म्हणून वापरल्या जाणारे प्रत्येक value-type क्लास दोन्ही सुसंगतपणे override केले पाहिजेत.
कोशा (bucket-then-equals lookup mechanism) समजून घेणे — आणि records किंवा generated code वापरून ते योग्यरित्या करणे — सुयोग्य वर्तनासाठी आवश्यक आहे आणि Java संग्रह कसे कार्य करतात याची खरी समज प्रकट करणारा क्लासिक मुलाखत विषय आहे.
सविस्तर उत्तरांसह IT मुलाखत प्रश्नांचे ग्रंथालय — Junior पासून Senior पर्यंत.
देणगी द्या