मैं समझ नहीं पा रहा हूं कि निम्नलिखित कोड में क्या हो रहा है जो मैंने लिखा है।

मैंने जो किया है, मेरे पास कुछ क्षेत्रों के साथ एक बाहरी वर्ग Employee है: id, panNo , नाम and पता . Then I have an inner class(it was not actually necessary to have it as an inner class) with आईडी and पैननो `क्षेत्र और उनके मूल्य इसके बाहरी वर्ग के सदस्यों के समान हैं।

मैं HashMaps के बारे में जो कुछ जानता हूं, उससे हम कुंजी-मूल्य वाले जोड़े को संग्रहीत करने के लिए उनका उपयोग करते हैं। कुंजी में hashcode मान होता है, और इस hashcode मूल्य के आधार पर मानों को व्यवस्थित किया जाता है। जब हम कुंजी की मदद से एक मान प्राप्त करते हैं, तो फिर से, इसके hashcode मूल्य का मूल्यांकन किया जाता है और फिर उचित मूल्य प्राप्त किया जाता है।

तो, hashmap कुछ इस तरह होना चाहिए:

कुंजी -----> इसका हैशकोड | संदर्भ फ़ील्ड --------> मान ऑब्जेक्ट का संदर्भ।

इसलिए जब मैं वस्तुओं को एक ही कुंजी के साथ सम्मिलित करने का प्रयास करता हूं, तो जो तत्व अंतिम डाला जाता है वह उपलब्ध है। ऐसा इसलिए है, क्योंकि वहाँ एक अद्वितीय कुंजी होनी चाहिए जिसका अर्थ है hashcode मान में केवल एक वस्तु का संदर्भ होना चाहिए।

अब, मैंने अपने कोड में क्या किया है, मैं नक्शे में Employee ऑब्जेक्ट सम्मिलित करता हूं और hashcode वर्ग को कुंजी के रूप में उपयोग किया है जो hashcode मान i.e 1 हर बार लौटाता है। इसलिए मेरी समझ के अनुसार, नक्शे में केवल एक तत्व होना चाहिए। लेकिन ऐसा नहीं हो रहा है ..... मुझे कुछ समझने की याद आ रही है।

मैंने निम्न वर्ग लिखा है:

 package package1;
 public class Employee {
     int id;
     int panNo;
     String name;
     String address;

     public Employee(int id, int panNo, String name, String address) {
        this.id = id;
        this.panNo = panNo;
        this.name = name;
        this.address = address;
 }

 @Override
 public String toString() {
      return "Employee [id=" + id + ", panNo=" + panNo + ", name=" +   name + ", address=" + address + "]";
 }

 public class EmployeeKey {
    int id = Employee.this.id;
    int panNo = Employee.this.panNo;

    @Override
    public int hashCode() {
        return 1;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        EmployeeKey other = (EmployeeKey) obj;
        if (!getOuterType().equals(other.getOuterType()))
            return false;
        if (id != other.id)
            return false;
        if (panNo != other.panNo)
            return false;
        return true;
    }

    private Employee getOuterType() {
        return Employee.this;
    }

  }
}

और एक परीक्षण वर्ग निम्नानुसार है:

 public class Test {
    public static void main(String[] args) {

       Employee e1 = new Employee(1, 123, "neeraj", "pune");
       Employee e2 = new Employee(2, 456, "viraaj", "pune");

       System.out.println(e1.new EmployeeKey().id);

       Map<Employee.EmployeeKey, Employee> myMap = new        HashMap<Employee.EmployeeKey, Employee>();
       myMap.put(e1.new EmployeeKey(), e1);
       myMap.put(e2.new EmployeeKey(), e2);

       System.out.println("Size:" + myMap.size());
       System.out.println("Hashcode of inner class e1: "
            + e1.new EmployeeKey().hashCode());
       System.out.println("Hashcode of inner class e2: "
            + e2.new EmployeeKey().hashCode());

        System.out.println(myMap.get(e1.new EmployeeKey()));
        System.out.println(myMap.get(e2.new EmployeeKey()));
   }
 }
-1
theimpatientcoder 4 पद 2015, 14:26

2 जवाब

सबसे बढ़िया उत्तर

नहीं, एक हैश तालिका कुंजी के लिए उपयोग करने के लिए "हैश बाल्टी" तय करने के लिए हैश कोड का उपयोग करती है। लेकिन हैश कोड अद्वितीय नहीं हैं। हमेशा टकराव की संभावना होती है, और यह वास्तव में अक्सर होता है।

इसलिए, एक उचित हैश तालिका केवल हैश कोड का उपयोग करता है, जहां तत्व को संग्रहीत करने के लिए पहले चरण के रूप में, लेकिन फिर उसे किसी प्रकार के टक्कर संकल्प का होना चाहिए - एक ही हैश कोड के साथ विभिन्न कुंजी को संग्रहीत करने का तरीका। इसका मतलब आमतौर पर हैश तालिका के प्रत्येक तत्व में एक लिंक की गई सूची या वास्तविक कुंजियों का एक पेड़ होता है।

जब आप हैश तालिका में एक कुंजी रखते हैं, तो यह पहले निर्णय लेने के लिए हैश कोड की गणना करता है। लेकिन फिर यह equals() विधि का उपयोग यह तय करने के लिए करता है कि क्या यह उस स्थिति में मौजूदा के रूप में समान कुंजी है। यदि यह है, तो नई प्रविष्टि पुराने की जगह लेगी, और चाबियाँ अद्वितीय रहेंगी। लेकिन अगर यह एक ही कुंजी नहीं है - equals() रिटर्न false - तो एक ही हैश कोड होने के बावजूद, नई कुंजी को अलग से जोड़ा जाएगा (लिंक की गई सूची या पेड़ में जोड़ा गया)।

जब आप कुंजी द्वारा एक मान प्राप्त करना चाहते हैं, तो फिर से, यह पहले चरण के रूप में हैश कोड की गणना करेगा, लेकिन फिर तालिका में उस स्थिति में सभी कुंजी के साथ कुंजी की तुलना करने के लिए equals() विधि का उपयोग करें। (लिंक की गई सूची या पेड़)। यह केवल तभी मान लौटाएगा जब कुंजी संग्रहीत है के बराबर है। यदि कोई समान कुंजी नहीं है, तो हालांकि हैश कोड समान है, कुंजी को समान नहीं माना जाता है।

यही कारण है कि हमेशा hashCode() और equals() दोनों तरीकों को एक साथ ओवरराइड करना महत्वपूर्ण है, और सुनिश्चित करें कि उनकी गणना ऑब्जेक्ट में एक ही फ़ील्ड के आधार पर की जाती है।

सभी वस्तुओं के लिए समान हैश कोड लौटाना आपकी हैश तालिका की विशिष्टता का उल्लंघन नहीं करने वाला है, बल्कि यह इसके प्रदर्शन को खराब करने वाला है, क्योंकि प्रभावी रूप से, हैश टेबल होने के बजाय, यह {X0}} की एक गणना पर आधारित है। और equals() कॉल्स की सीमित संख्या में, आपके पास हैश तालिका में एक प्रभावी सेल है, और आपकी डेटा संरचना एक लिंक की गई सूची या ट्री बन गई है - रैखिक खोज का उपयोग किया जाता है।

1
RealSkeptic 4 पद 2015, 11:45

यहां HashMap में कुंजी लुकअप के चरण हैं।

  1. key.hashCode() का उपयोग करके कुंजी का hash प्राप्त करें।
  2. बाल्टी को खोजने के लिए उस हैश का उपयोग करें जिसे इस कुंजी को रखा जाना चाहिए था।
  3. कुंजी की तुलना करने के लिए equals का उपयोग करके उस बाल्टी में प्रत्येक कुंजी की जांच करके कुंजी के लिए उस बाल्टी को खोजें।

आपने hashCode रिटर्न 1 हमेशा किया है, इसलिए आपके सभी आइटम एक ही बाल्टी में रखे जाएंगे, लेकिन आपके equals अभी भी दो कुंजी के लिए false वापस आ जाएंगे।

    Employee e1 = new Employee(1, 123, "neeraj", "pune");
    Employee e2 = new Employee(2, 456, "viraaj", "pune");

    System.out.println(e1.new EmployeeKey().id);

    Map<Employee.EmployeeKey, Employee> myMap = new HashMap<Employee.EmployeeKey, Employee>();
    Employee.EmployeeKey k1 = e1.new EmployeeKey();
    myMap.put(k1, e1);
    Employee.EmployeeKey k2 = e2.new EmployeeKey();
    myMap.put(k2, e2);

    System.out.println("Size:" + myMap.size());
    System.out.println("Hashcode of inner class e1: "
            + e1.new EmployeeKey().hashCode());
    System.out.println("Hashcode of inner class e2: "
            + e2.new EmployeeKey().hashCode());
    System.out.println("Equals of keys: "
            + k1.equals(k2));

    System.out.println(myMap.get(e1.new EmployeeKey()));
1
OldCurmudgeon 4 पद 2015, 11:44