আমার জাভাতে সমান এবং হ্যাশকোড পদ্ধতিগুলিকে ওভাররাইড করার দরকার কী?


383

সম্প্রতি আমি এই বিকাশকারী ওয়ার্কস ডকুমেন্টের মাধ্যমে পড়েছি ।

ডকুমেন্টটি সমস্ত সংজ্ঞায়িত hashCode()এবং equals()কার্যকর এবং সঠিকভাবে সম্পর্কে , তবে কেন এই দুটি পদ্ধতির ওভাররাইড করা দরকার তা আমি বুঝতে সক্ষম হচ্ছি না।

এই পদ্ধতিগুলি দক্ষতার সাথে প্রয়োগ করার সিদ্ধান্ত আমি কীভাবে নিতে পারি?


4
প্রোগ্রামিং.গুইডে এখানে দুটি দুর্দান্ত নিবন্ধ রয়েছে ঠিক এটি ব্যাখ্যা করে: কখন আমার সমানগুলি ওভাররাইড করা উচিত? এবং কেন আপনি সবসময় যখন সমান অগ্রাহ্য হ্যাশকোড ওভাররাইড করা উচিত । (সতর্কতা, গৃহীত উত্তরটি আসলে ভুল))
আইওব

কেস ওভাররাইড কেবল সমান: দুটি একই বস্তুর বিভিন্ন হ্যাশকোড থাকবে = একই বস্তু বিভিন্ন বালতিতে (নকল)। কেস ওভাররাইড কেবল হ্যাশকোড: দুটি একই বস্তুর একই হ্যাশকোড = একই বস্তু একই বালতিতে যাবে (সদৃশ)।
VdeX

উত্তর:


524

জোশুয়া ব্লচ কার্যকর জাভা সম্পর্কে বলেছেন

সমান () সমেত ওভাররাইড করে এমন প্রতিটি শ্রেণিতে আপনাকে অবশ্যই হ্যাশকোড () ওভাররাইড করতে হবে। এটি ব্যর্থ হওয়ার ফলে অবজেক্ট.হ্যাশকোড () এর সাধারণ চুক্তি লঙ্ঘন হবে, যা হ্যাশম্যাপ, হ্যাশসেট এবং হ্যাশটেবল সহ সমস্ত হ্যাশ-ভিত্তিক সংগ্রহের সাথে একত্রে আপনার শ্রেণিকে সঠিকভাবে কাজ করা থেকে বিরত করবে।

আসুন আমরা এটিকে ওভাররাইড equals()না করে ওভাররাইড না করে কী কী হবে তার উদাহরণ দিয়ে বোঝার চেষ্টা করি hashCode()এবং একটি ব্যবহার করার চেষ্টা করি Map

বলুন আমাদের মতো একটি বর্গ রয়েছে এবং এর দুটি বস্তু MyClassসমান হলে importantFieldএটি ( সমগ্রহ দ্বারা hashCode()এবং এর equals()দ্বারা উত্পন্ন)

public class MyClass {

    private final String importantField;
    private final String anotherField;

    public MyClass(final String equalField, final String anotherField) {
        this.importantField = equalField;
        this.anotherField = anotherField;
    }

    public String getEqualField() {
        return importantField;
    }

    public String getAnotherField() {
        return anotherField;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((importantField == null) ? 0 : importantField.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyClass other = (MyClass) obj;
        if (importantField == null) {
            if (other.importantField != null)
                return false;
        } else if (!importantField.equals(other.importantField))
            return false;
        return true;
    }

}

শুধুমাত্র ওভাররাইড করুন equals

যদি কেবল equalsওভাররেড করা হয় তবে আপনি যখন myMap.put(first,someValue)প্রথমে কল করবেন তখন কিছু বালতিতে হ্যাশ হবে এবং যখন আপনি কল করবেন তখন myMap.put(second,someOtherValue)এটি অন্য কোনও বালতিতে হ্যাশ করবে (যেমন তাদের আলাদা রয়েছে hashCode)। সুতরাং, যদিও তারা সমান, তারা একই বালতিতে হ্যাশ করে না, মানচিত্রটি এটি উপলব্ধি করতে পারে না এবং উভয়ই মানচিত্রে থাকে।


যদিও equals()আমরা ওভাররাইড করলে ওভাররাইড করা প্রয়োজন হয় না hashCode(), আসুন দেখুন এই বিশেষ ক্ষেত্রে কী ঘটবে যেখানে আমরা জানি যে দুটি বস্তু MyClassসমান হলে তারা importantFieldসমান হয় তবে আমরা ওভাররাইড করি না equals()

শুধুমাত্র ওভাররাইড করুন hashCode

আপনি এটা আছে কল্পনা

MyClass first = new MyClass("a","first");
MyClass second = new MyClass("a","second");

যদি আপনি কেবল ওভাররাইড করেন hashCodeতবে আপনি যখন কল করবেন তখন myMap.put(first,someValue)প্রথমে লাগে, এর গণনা করে hashCodeএটি একটি প্রদত্ত বালতিতে সঞ্চয় করে। তারপরে আপনি যখন ফোন করবেন তখন মানচিত্রের ডকুমেন্টেশন অনুসারে myMap.put(second,someOtherValue)এটি দ্বিতীয়টির সাথে প্রতিস্থাপন করা উচিত কারণ তারা সমান (ব্যবসায়ের প্রয়োজনীয়তা অনুসারে)।

কিন্তু সমস্যা যে সমান পুনরায় সংজ্ঞায়িত করা হয় নি, তাই যখন মানচিত্র হ্যাশ হয় secondএবং iterates বালতি মাধ্যমে আছে যদি একটি বস্তু খুঁজছেন kযেমন যে second.equals(k)সত্য এটা কোনো হিসাবে পাবে না হয় second.equals(first)হতে হবে false

আশা করি এটা পরিষ্কার ছিল


5
আপনি কি দয়া করে আরও কিছুটা ব্যাখ্যা করতে পারেন, দ্বিতীয় ক্ষেত্রে, দ্বিতীয় বস্তুকে কেন অন্য বালতিতে যেতে হবে?
হুসেন আক্তার ওয়াহিদ 'গৌরি'

57
আমি এই উত্তরটি পছন্দ করি না কারণ এটি প্রস্তাব দেয় যে সমান () এর চেয়ে ওভাররাইড না করে আপনি হ্যাশকোড () কে ওভাররাইড করতে পারবেন না, যা কেবল সত্য নয়। আপনি বলছেন যে আপনার উদাহরণ কোডটি ("ওভাররাইড কেবল হ্যাশকোড" অংশ) কাজ করবে না কারণ আপনি আপনার দুটি বস্তুকে সমান হিসাবে সংজ্ঞায়িত করেছেন , তবে - দুঃখিত - এই সংজ্ঞাটি কেবল আপনার মাথায় রয়েছে। আপনার প্রথম উদাহরণে আপনার কাছে একই হ্যাশকোড সহ দুটি সম-সম-বস্তু রয়েছে এবং এটি পুরোপুরি আইনী। সুতরাং আপনাকে সমান () এর ওভাররাইড করার কারণটি এই নয় যে আপনি ইতিমধ্যে হ্যাশকোড () কে ওভাররাইড করেছেন, তবে আপনি আপনার "সমান" সংজ্ঞাটি আপনার মাথা থেকে কোডে সরিয়ে নিতে চান।
ব্যবহারকারী 2543253

11
if you think you need to override one, then you need to override both of themভূল. hashCodeআপনার শ্রেণিটি যদি ওভাররাইড করে equalsতবে বিপরীতটি সত্য না হলে আপনাকে ওভাররাইড করতে হবে।
akhil_mittal

4
আমি মনে করি ঠিক একইভাবে ওভাররাইড না করে কেবল হ্যাশকোড () ওভাররাইড করা পুরোপুরি ঠিক । এটি কার্যকর জাভাতেও কি লেখা আছে : books.google.fr/…
জনি

2
@ ফ্যান্টম রেফারেন্স, নোট করুন যে কেবল ওভাররাইডিং equalsএর জবাডোকের মধ্যে বর্ণিত চুক্তি লঙ্ঘন করবে Object: "যদি equals(Object)পদ্ধতি অনুসারে দুটি বস্তু সমান হয় , তবে hashCodeদুটি বস্তুর প্রতিটিতে পদ্ধতিটি কল করা অবশ্যই একই পূর্ণসংখ্যার ফলাফল উত্পন্ন করতে হবে।" অবশ্যই, সমস্ত চুক্তির সমস্ত অংশই সমস্ত কোডে প্রয়োগ করা হয় না তবে তবুও, আনুষ্ঠানিকভাবে বলতে গেলে এটি লঙ্ঘন এবং আমি এটি হওয়ার জন্য অপেক্ষা করা একটি বাগ হিসাবে বিবেচনা করব।
আইয়ুব

263

যেমন সংগ্রহগুলি HashMapএবং HashSetএকটি ব্যবহার হ্যাশকোড একটি বস্তুর মান নির্ধারণ করতে কিভাবে এটা একটি সংগ্রহ ভিতরে সংরক্ষণ করা উচিত, এবং হ্যাশকোড যাতে এর সংগ্রহ বস্তুর খোজা মধ্যে আবার ব্যবহার করা হয়।

হ্যাশিং পুনরুদ্ধার একটি দ্বি-পদক্ষেপ প্রক্রিয়া:

  1. ডান বালতিটি (ব্যবহার করে hashCode()) সন্ধান করুন
  2. সঠিক উপাদানটির জন্য বালতিটি অনুসন্ধান করুন (ব্যবহার করে equals())

আমাদের কেন ওভাররাইড করা উচিত equals()এবং তার একটি ছোট উদাহরণ এখানে hashcode()

একটি Employeeশ্রেণী বিবেচনা করুন যার দুটি ক্ষেত্র রয়েছে: বয়স এবং নাম।

public class Employee {

    String name;
    int age;

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (!(obj instanceof Employee))
            return false;
        Employee employee = (Employee) obj;
        return employee.getAge() == this.getAge()
                && employee.getName() == this.getName();
    }

    // commented    
    /*  @Override
        public int hashCode() {
            int result=17;
            result=31*result+age;
            result=31*result+(name!=null ? name.hashCode():0);
            return result;
        }
     */
}

এখন একটি শ্রেণী তৈরি করুন, একটিতে Employeeবস্তু সন্নিবেশ করুন HashSetএবং সেই বস্তুটি উপস্থিত আছে কি না তা পরীক্ষা করুন।

public class ClientTest {
    public static void main(String[] args) {
        Employee employee = new Employee("rajeev", 24);
        Employee employee1 = new Employee("rajeev", 25);
        Employee employee2 = new Employee("rajeev", 24);

        HashSet<Employee> employees = new HashSet<Employee>();
        employees.add(employee);
        System.out.println(employees.contains(employee2));
        System.out.println("employee.hashCode():  " + employee.hashCode()
        + "  employee2.hashCode():" + employee2.hashCode());
    }
}

এটি নিম্নলিখিত মুদ্রণ করবে:

false
employee.hashCode():  321755204  employee2.hashCode():375890482

এখন অসাধারণ hashcode()পদ্ধতি, একই চালানো এবং আউটপুট হবে:

true
employee.hashCode():  -938387308  employee2.hashCode():-938387308

এখন আপনি দেখতে পাচ্ছেন যে কেন দুটি বস্তু সমান হিসাবে বিবেচিত হয়, তবে তাদের হ্যাশকোডগুলিও সমান হতে হবে? অন্যথায়, আপনি কখনই অবজেক্টটি সন্ধান করতে পারবেন না যেহেতু ক্লাস অবজেক্টে ডিফল্ট হ্যাশকোড পদ্ধতি কার্যত সর্বদা প্রতিটি বস্তুর জন্য একটি স্বতন্ত্র সংখ্যা নিয়ে আসে, এমনকি যদি equals()পদ্ধতিটি এমনভাবে উপেক্ষা করা হয় যে দুটি বা ততোধিক বস্তু সমান হিসাবে বিবেচিত হয় । যদি তাদের হ্যাশকোডগুলি এর প্রতিফলন না করে তবে বস্তুগুলি কতটা সমান তা বিবেচনা করে না । সুতরাং আরও একবার: দুটি বস্তু সমান হলে তাদের হ্যাশকোডগুলিও সমান হতে হবে।


4
নিখুঁত উদাহরণ। স্পষ্টভাবে পার্থক্য প্রদর্শিত!
কোডারপিসি

3
@ রাজীব
VdeX

2
@ ভিকাস ভার্মা সমান অবজেক্টটির সমান হ্যাশকোড থাকবে না এর অর্থ অসম বস্তুতে অসম হ্যাশকোড থাকবে। যদি বস্তুগুলি আসলে আলাদা হয় তবে তাদের হ্যাশকোড একই হয় তবে কী হবে?
রবি

1
খুব সুন্দরভাবে ব্যাখ্যা করেছেন :)
রাহুল

4
আরও ভাল উত্তর তারপর গৃহীত উত্তর! ধন্যবাদ
ড্রিফটউড

50

সমান () সমেত ওভাররাইড করে এমন প্রতিটি শ্রেণিতে আপনাকে অবশ্যই হ্যাশকোড () ওভাররাইড করতে হবে। এটি ব্যর্থ হওয়ার ফলে অবজেক্ট.হ্যাশকোড () এর সাধারণ চুক্তি লঙ্ঘন হবে, যা হ্যাশম্যাপ, হ্যাশসেট এবং হ্যাশটেবল সহ সমস্ত হ্যাশ-ভিত্তিক সংগ্রহের সাথে একত্রে আপনার শ্রেণিকে সঠিকভাবে কাজ করা থেকে বিরত করবে।


কার্যকর জাভা    থেকে , জোশুয়া ব্লচ দ্বারা

সংজ্ঞায়িত করে equals()এবং hashCode()ধারাবাহিকভাবে, আপনি হ্যাশ-ভিত্তিক সংগ্রহগুলির কী হিসাবে আপনার শ্রেণীর ব্যবহারের দক্ষতা উন্নত করতে পারেন। যেমন হ্যাশকোডের জন্য এপিআই ডকটি ব্যাখ্যা করে: "এই পদ্ধতিটি হ্যাশ টেবিলের সুবিধার্থে সমর্থিত যেমন সরবরাহ করে java.util.Hashtable।"

কীভাবে এই পদ্ধতিগুলি দক্ষতার সাথে প্রয়োগ করতে হবে সে সম্পর্কে আপনার প্রশ্নের সেরা উত্তর আপনাকে কার্যকর জাভার ৩ য় অধ্যায়টি পড়ার পরামর্শ দিচ্ছে ।


4
এটি সঠিক উত্তর। অবশ্যই অস্তিত্বের সত্যতা অবলম্বন করার জন্য যে আপনি যদি কখনও হ্যাশ-ভিত্তিক সংগ্রহের ক্লাস ব্যবহার করেন না, তবে আপনি বাস্তবায়ন করেননি তাতে কিছু যায় আসে না hashCode()
পাতলা

1
আরও জটিল ক্ষেত্রে, আপনি কখনই জানেন না যে আপনি যে সংগ্রহগুলি ব্যবহার করেন তা হ্যাশ ব্যবহার করছে কিনা, তাই "আপনি হ্যাশকোড () প্রয়োগ করেননি এটির কোনও ব্যাপার নেই"
ভিক্টর সার্জিয়েনকো

1
সমান () সমীক্ষা ছাড়াই আমি কি হ্যাশকোড () কে ওভাররাইড করতে পারি?
জনি

@ স্ট্যাসস, হ্যাঁ, গৃহীত উত্তর যা বলে তার বিপরীতে। এই নিবন্ধের দ্বিতীয় অংশে ব্যাখ্যা দেখুন: সমান ওভাররাইড করার সময় আপনার কেন সর্বদা হ্যাশকোডকে ওভাররাইড করা উচিত
আইওউব

22

সোজা কথায়, রেফারেন্সের সমতার জন্য অবজেক্ট চেকের সমান-পদ্ধতিটি যেখানে আপনার শ্রেণীর দুটি উদাহরণ এখনও শব্দার্থিকভাবে সমান হতে পারে যখন বৈশিষ্ট্য সমান হয়। হ্যাশম্যাপ এবং সেট এর মতো সমান এবং হ্যাশকোড ব্যবহার করে এমন কোনও ধারকটিতে আপনার বস্তুগুলি রাখার ক্ষেত্রে এটি উদাহরণস্বরূপ গুরুত্বপূর্ণ । ধরা যাক আমাদের মতো ক্লাস রয়েছে:

public class Foo {
    String id;
    String whatevs;

    Foo(String id, String whatevs) {
        this.id = id;
        this.whatevs = whatevs;
    }
}

আমরা একই আইডি দিয়ে দুটি দৃষ্টান্ত তৈরি করি :

Foo a = new Foo("id", "something");
Foo b = new Foo("id", "something else");

ওভাররাইডিং সমান সমেত আমরা পাচ্ছি:

  • a.equals (খ) মিথ্যা কারণ তারা দুটি পৃথক দৃষ্টান্ত
  • a.equals (ক) এটি একই উদাহরণ থেকে সত্য
  • b.equals (খ) সত্য কারণ এটি একই উদাহরণ

সঠিক? ঠিক আছে, যদি আপনি এটি চান এটি। তবে ধরা যাক আমরা দুটি পৃথক দৃষ্টান্ত না রেখেই একই আইডি সহ অবজেক্টগুলি একই জিনিস হতে চাই। আমরা সমান ওভাররাইড (এবং হ্যাশকোড):

public class Foo {
    String id;
    String whatevs;

    Foo(String id, String whatevs) {
        this.id = id;
        this.whatevs = whatevs;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Foo) {
            return ((Foo)other).id.equals(this.id);   
        }
    }

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

সমান এবং হ্যাশকোড বাস্তবায়নের জন্য আমি পেয়ারা এর সহায়ক পদ্ধতি ব্যবহার করার পরামর্শ দিতে পারি


20

পরিচয় সাম্য নয়।

  • সমান অপারেটর == পরীক্ষার পরিচয় ।
  • equals(Object obj) পদ্ধতিটি সমতা পরীক্ষার সাথে তুলনা করে (অর্থাত্ পদ্ধতিটি ওভাররাইড করে আমাদের সমতা বলতে হবে)

আমার জাভাতে সমান এবং হ্যাশকোড পদ্ধতিগুলিকে ওভাররাইড করার দরকার কী?

প্রথমে আমাদের সমান পদ্ধতির ব্যবহার বুঝতে হবে।

দুটি বস্তুর মধ্যে পরিচয়ের পার্থক্যের জন্য আমাদের সমান পদ্ধতিটিকে ওভাররাইড করতে হবে।

উদাহরণ স্বরূপ:

Customer customer1=new Customer("peter");
Customer customer2=customer1;
customer1.equals(customer2); // returns true by JVM. i.e. both are refering same Object
------------------------------
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
customer1.equals(customer2); //return false by JVM i.e. we have two different peter customers.

------------------------------
Now I have overriden Customer class equals method as follows:
 @Override
    public boolean equals(Object obj) {
        if (this == obj)   // it checks references
            return true;
        if (obj == null) // checks null
            return false;
        if (getClass() != obj.getClass()) // both object are instances of same class or not
            return false;
        Customer other = (Customer) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name)) // it again using bulit in String object equals to identify the difference 
            return false;
        return true; 
    }
Customer customer1=new Customer("peter");
Customer customer2=new Customer("peter");
Insteady identify the Object equality by JVM, we can do it by overring equals method.
customer1.equals(customer2);  // returns true by our own logic

এখন হ্যাশকোড পদ্ধতিটি সহজেই বুঝতে পারবেন।

হ্যাশকোড হ্যাশম্যাপ , হ্যাশসেটের মতো ডেটা স্ট্রাকচারে অবজেক্ট সংরক্ষণ করার জন্য পূর্ণসংখ্যা উত্পাদন করে ।

ধরে নিন আমাদের Customerউপরে ওভাররাইড সমান পদ্ধতি রয়েছে ,

customer1.equals(customer2);  // returns true by our own logic

যখন আমরা বালতিতে বস্তু সঞ্চয় করি তখন ডেটা স্ট্রাকচারের সাথে কাজ করার সময় (বালতি ফোল্ডারের জন্য অভিনব নাম)। যদি আমরা অন্তর্নির্মিত হ্যাশ কৌশলটি ব্যবহার করি তবে উপরের দুটি গ্রাহকের জন্য এটি দুটি পৃথক হ্যাশকোড উত্পন্ন করে। সুতরাং আমরা একই পৃথক দুটি জিনিস দুটি পৃথক স্থানে সংরক্ষণ করছি। এই ধরণের সমস্যা এড়াতে আমাদের নীচের নীতিগুলির ভিত্তিতে হ্যাশকোড পদ্ধতি ওভাররাইড করা উচিত।

  • আন-সমমানের দৃষ্টান্তগুলিতে একই হ্যাশকোড থাকতে পারে।
  • সমান দৃষ্টান্তগুলি একই হ্যাশকোডে ফিরে আসবে।

3
গত ১ ঘন্টা ধরে আমি এটির সন্ধান করছিলাম। অসাধারণ সাথী (y)
আদনান

13

ঠিক আছে, আমাকে ধারণাটি খুব সাধারণ কথায় ব্যাখ্যা করতে দিন।

প্রথমত বিস্তৃত দৃষ্টিকোণ থেকে আমাদের সংগ্রহ রয়েছে এবং সংগ্রহগুলির মধ্যে হ্যাশম্যাপটি একটি ডেটাস্ট্রাকচার।

কেন আমাদের উভয় সমতুল্য এবং হ্যাশকোড পদ্ধতি ওভাররাইড করতে হবে তা বোঝার জন্য, প্রথমে হ্যাশম্যাপ কী এবং কী তা বোঝার প্রয়োজন হয়।

একটি হ্যাশম্যাপ এমন একটি ডেটাস্ট্রাকচার যা অ্যারের ফ্যাশনে মূল মান জোড় ডেটা সঞ্চয় করে। একটি [] বলতে দিন, যেখানে 'ক' এর প্রতিটি উপাদান একটি মূল মান জুটি।

এছাড়াও উপরের অ্যারেতে প্রতিটি সূচি লিঙ্কযুক্ত লিঙ্কযুক্ত হতে পারে যার ফলে একটি সূচকে একাধিক মান থাকে values

এখন কেন একটি হ্যাশম্যাপ ব্যবহার করা হয়? যদি আমাদের একটি বৃহত অ্যারেগুলির মধ্যে অনুসন্ধান করতে হয় তবে প্রতিটিটির মাধ্যমে অনুসন্ধান করা যদি সেগুলি দক্ষ না হয় তবে হ্যাশ কৌশলটি আমাদের কী বলে যা কিছু যুক্তি দিয়ে অ্যারে প্রসেস করতে দেয় এবং সেই লজিকের উপর ভিত্তি করে উপাদানগুলি গ্রুপ করে দেয় যেমন হ্যাশিং

উদাহরণস্বরূপ: আমাদের কাছে অ্যারে রয়েছে 1,2,3,4,5,6,7,8,9,10,11 এবং আমরা একটি হ্যাশ ফাংশন মড 10 প্রয়োগ করি যাতে 1,11 একসাথে গ্রুপ করা হবে। সুতরাং যদি আমাদের পূর্ববর্তী অ্যারেতে 11 টি অনুসন্ধান করতে হয় তবে আমাদের সম্পূর্ণ অ্যারেটি পুনরাবৃত্তি করতে হবে তবে যখন আমরা এটির গোষ্ঠী করি তখন আমরা আমাদের পুনরাবৃত্তির সুযোগকে সীমাবদ্ধ করি যার দ্বারা গতি উন্নতি হয়। উপরের সমস্ত তথ্য সংরক্ষণ করার জন্য ব্যবহৃত এই ডেটাস্ট্রাকচারটিকে সরলতার জন্য 2 ডি অ্যারে হিসাবে ভাবা যেতে পারে

উপরের হ্যাশম্যাপটি ছাড়াও আরও জানায় যে এটি এতে কোনও ডুপ্লিকেট যুক্ত করবে না। এবং এটি আমাদের সমান এবং হ্যাশকোডকে ওভাররাইড করার মূল কারণ

সুতরাং যখন এটি বলেছে যে হ্যাশম্যাপের অভ্যন্তরীণ কার্যকারিতা ব্যাখ্যা করে, আমাদের হ্যাশম্যাপের কী পদ্ধতি রয়েছে এবং এটি উপরের বিধিগুলি অনুসরণ করে যা আমি উপরে বর্ণিত তা অনুসরণ করতে হবে

সুতরাং হ্যাশম্যাপে পুট (কে, ভি) নামে পরিচিত পদ্ধতি রয়েছে এবং হ্যাশম্যাপ অনুসারে এটি দক্ষতার সাথে অ্যারে বিতরণ এবং কোনও সদৃশ যোগ না করার উপরোক্ত নিয়মগুলি অনুসরণ করা উচিত

সুতরাং যা করা যায় তা হ'ল প্রথমে প্রদত্ত কীটির জন্য হ্যাশকোড তৈরি করা হবে যা নির্ধারণ করবে যে মানটি কোন ইনডেক্সে প্রবেশ করা উচিত if যদি সেই সূচীতে কিছু উপস্থিত না থাকে তবে নতুন মানটি সেখানে যুক্ত করা হবে, যদি সেখানে ইতিমধ্যে কিছু উপস্থিত থাকে তবে তারপরে সেই সূচীতে লিঙ্কযুক্ত তালিকার শেষে নতুন মান যুক্ত করা উচিত। তবে মনে রাখবেন হ্যাশম্যাপের পছন্দসই আচরণ অনুযায়ী কোনও সদৃশ যুক্ত করা উচিত নয়। সুতরাং আসুন আমরা বলি যে আপনার দুটি পূর্ণসংখ্যার বস্তু রয়েছে aa = 11, বিবি = 11। প্রতিটি বস্তু যেমন বস্তু শ্রেণি থেকে প্রাপ্ত, দুটি বস্তুর তুলনা করার জন্য ডিফল্ট বাস্তবায়ন হ'ল এটি রেফারেন্সটির সাথে তুলনা করে এবং বস্তুর অভ্যন্তরের মানগুলি না not উপরের ক্ষেত্রে উভয় ক্ষেত্রে যদিও শব্দার্থগতভাবে সমান সমতা পরীক্ষায় ব্যর্থ হবে এবং একই হ্যাশকোড এবং একই মান দুটি কার্যকর করার ফলে নকল তৈরির সম্ভাবনা রয়েছে। আমরা যদি ওভাররাইড করে থাকি তবে আমরা নকলগুলি এড়াতে পারি। আপনি উল্লেখ করতে পারেবিস্তারিত কাজ

import java.util.HashMap;


public class Employee {

String name;
String mobile;
public Employee(String name,String mobile) {
    this.name=name;
    this.mobile=mobile;
}

@Override
public int hashCode() {
    System.out.println("calling hascode method of Employee");
    String str=this.name;
    Integer sum=0;
    for(int i=0;i<str.length();i++){
        sum=sum+str.charAt(i);
    }
    return sum;

}
@Override
public boolean equals(Object obj) {
    // TODO Auto-generated method stub
    System.out.println("calling equals method of Employee");
    Employee emp=(Employee)obj;
    if(this.mobile.equalsIgnoreCase(emp.mobile)){

        System.out.println("returning true");
        return true;
    }else{
        System.out.println("returning false");
        return false;
    }


}

public static void main(String[] args) {
    // TODO Auto-generated method stub

    Employee emp=new Employee("abc", "hhh");
    Employee emp2=new Employee("abc", "hhh");
    HashMap<Employee, Employee> h=new HashMap<>();
    //for (int i=0;i<5;i++){
        h.put(emp, emp);
        h.put(emp2, emp2);

    //}

    System.out.println("----------------");
    System.out.println("size of hashmap: "+h.size());


}

}

আমার একটি বিভ্রান্তি আছে, কেন আমরা যখন হ্যাশম্যাপের ক্ষেত্রে হ্যাশকোড পদ্ধতি ওভাররাইড করি তখন সমান পদ্ধতিটি কেন আমাদের ওভাররাইড করা দরকার? যে কোনও ক্ষেত্রে, হ্যাশম্যাপ মানটির পরিবর্তে যদি বস্তুর হ্যাশকোড সমান হয়।
বিকাশ ভার্মা

@ ভিকাস ভার্মা হ্যাশম্যাপ কোনও ধরণের মান প্রতিস্থাপন করে না যদি বস্তুর হ্যাশকোড সমান হয় তবে এটি কেবলমাত্র সূচি স্থির করে যেখানে হ্যাশম্যাপে নতুন যুক্ত হওয়া বস্তুটি স্থাপন করতে হবে। সূচীতে এখন অবজেক্টগুলি থাকতে পারে, তাই অনুলিপি এড়াতে আমরা সমান পদ্ধতিটি ওভাররাইড করি এবং যখন তুলনামূলকভাবে দুটি বস্তু সমান হিসাবে বিবেচনা করা হয় তখন আমরা সংজ্ঞায়নের জন্য যুক্তি লিখি। যদি ওভাররাইড না করা হয় তবে একই মানযুক্ত বস্তু সংরক্ষণ করা হবে কারণ উভয় বস্তুর রেফারেন্স আলাদা হবে
চেতান

11

hashCode() :

আপনি যদি হ্যাশ-কোড পদ্ধতিটিকে ওভাররাইড করেন তবে কিছুই হবে না। কারণ এটি সর্বদা নতুন ফিরে আসেhashCode প্রতিটি বস্তুর জন্য অবজেক্ট শ্রেণি হিসাবে ।

equals() :

আপনি যদি কেবলমাত্র সমান পদ্ধতিটিকে ওভাররাইড করেন a.equals(b)তবে সত্য এটি এর অর্থ hashCodeএকটি এবং বি এর অবশ্যই হওয়া উচিত তবে ঘটবে না। কারণ আপনি ওভাররাইড করেননিhashCode পদ্ধতিটিকে ।

দ্রষ্টব্য: hashCode()অবজেক্ট শ্রেণির পদ্ধতি সর্বদা hashCodeপ্রতিটি বস্তুর জন্য নতুন ফিরে আসে ।

সুতরাং যখন আপনার হ্যাশিং ভিত্তিক সংগ্রহটিতে আপনার অবজেক্টটি ব্যবহার করার দরকার হবে তখন অবশ্যই equals()এবং উভয়ই ওভাররাইড করতে হবে hashCode()


এটি আকর্ষণীয় বিষয়, ওভাররাইড সম্পর্কে কেবল হ্যাশকোড () । এটা পুরোপুরি ঠিক আছে, তাই না? নাকি সমস্যাজনিত মামলাও হতে পারে?
জনি

1
এটি একটি বিভ্রান্তিমূলক এবং ভুল উত্তর। ওভাররাইডিং (= কেবল =) হ্যাশকোড () নিশ্চিত করে যে অনুরূপ বৈশিষ্ট্যযুক্ত স্বতন্ত্র শ্রেণিতে ইনস্ট্যান্ট করা প্রতিটি বস্তু একই হ্যাশ কোড বহন করে। তবে কার্যকর হবে না কারণ এগুলির কোনওটি একে অপরের সমান হবে না।
এমফায়সালহাইডার

8

জাভা একটি নিয়ম রাখে যে

"যদি বস্তু শ্রেণীর সমান পদ্ধতি ব্যবহার করে দুটি বস্তু সমান হয়, তবে হ্যাশকোড পদ্ধতিতে এই দুটি বস্তুর জন্য একই মান দেওয়া উচিত" "

সুতরাং, আমাদের ক্লাসে যদি আমরা ওভাররাইড equals()করি তবে আমাদের hashcode()এই নিয়মটি অনুসরণ করার পদ্ধতিও ওভাররাইড করা উচিত । উভয় পদ্ধতি equals()এবং hashcode(), Hashtableউদাহরণস্বরূপ, মান-কী জোড়া হিসাবে মান সংরক্ষণ করতে ব্যবহৃত হয় । যদি আমরা একটিটিকে ওভাররাইড করি এবং অপরটি না করে, এমন সম্ভাবনা রয়েছে যা Hashtableআমরা যেমন চাই তেমন কাজ না করে, যদি আমরা এই জাতীয় অবজেক্টটিকে কী হিসাবে ব্যবহার করি।


6

কারণ আপনি যদি এগুলি ওভাররাইড না করেন তবে আপনি অবজেক্টে ডিফল্ট ইমপ্লেটেশন ব্যবহার করবেন।

উদাহরণস্বরূপ সাম্যতা এবং হ্যাশকোড মানগুলি প্রদত্ত সাধারণভাবে কোন জ্ঞান প্রয়োজন যা কোনও বস্তু তৈরি করে তা সাধারণত আপনার শ্রেণিতে কোনও স্পষ্ট অর্থের জন্য পুনরায় সংজ্ঞায়িত হওয়া প্রয়োজন।


6

হ্যাশম্যাপ, হ্যাশটেবল ইত্যাদি সংগ্রহের জন্য কী হিসাবে আমাদের নিজস্ব শ্রেণীর অবজেক্টগুলি ব্যবহার করার জন্য, আমাদের সংগ্রহের অভ্যন্তরীণ কাজ সম্পর্কে সচেতনতা রেখে উভয় পদ্ধতি (হ্যাশকোড () এবং সমান ()) ওভাররাইড করা উচিত। অন্যথায়, এটি ভুল ফলাফল নিয়ে যায় যা আমাদের প্রত্যাশিত হয় না।


6

@ লম্বোর জবাব যোগ করা

সমান () সমেত আপনাকে কখন ওভাররাইড করতে হবে?

অবজেক্টের সমান () এর ডিফল্ট বাস্তবায়ন

public boolean equals(Object obj) {
        return (this == obj);
}

যার অর্থ দুটি বস্তু কেবল তখনই সমান হিসাবে বিবেচিত হবে যদি তাদের কাছে একই মেমরি ঠিকানা থাকে যা আপনি যদি কোনও বস্তুর সাথে নিজেকে তুলনা করে থাকেন তবেই এটি সত্য হবে।

তবে আপনি দুটি বস্তুকে একই বিবেচনা করতে চাইতে পারেন যদি তাদের এক বা একাধিক বৈশিষ্ট্যের জন্য একই মান থাকে (@ লম্বোর উত্তরে প্রদত্ত উদাহরণটি দেখুন)।

সুতরাং আপনি equals()এই পরিস্থিতিতে ওভাররাইড করবেন এবং সাম্যের জন্য আপনি নিজের শর্ত দেবেন।

আমি সফলভাবে সমান () কার্যকর করেছি এবং এটি দুর্দান্ত কাজ করছে is সুতরাং কেন তারা হ্যাশকোড () পাশাপাশি ওভাররাইড করতে বলছে?

ওয়েল.আপনি আপনার ব্যবহারকারী-সংজ্ঞায়িত শ্রেণিতে "হ্যাশ" ভিত্তিক সংগ্রহগুলি ব্যবহার করবেন না , এটি ঠিক আছে। তবে ভবিষ্যতে কিছু সময় আপনি ব্যবহার করতে পারেন HashMapবাHashSet এবং যদি আপনি না overrideএবং হ্যাশকোড () "সঠিকভাবে বাস্তবায়ন" , এই হ্যাশ ভিত্তিক সংগ্রহ হিসাবে উদ্দীষ্ট কাজ করবে না।

ওভাররাইড কেবল সমান (@ লম্বোর জবাব যোগ করা)

myMap.put(first,someValue)
myMap.contains(second); --> But it should be the same since the key are the same.But returns false!!! How?

সবার আগে, হ্যাশম্যাপ চেক করে যে হ্যাশকোডের secondমতো হয় first। মানগুলি একই হলে, এটি একই বালতিতে সাম্যতা যাচাই করতে এগিয়ে যায়।

তবে এখানে এই 2 টি অবজেক্টের জন্য হ্যাশকোড আলাদা (কারণ তাদের ডিফল্ট বাস্তবায়ন থেকে মেমরির ঠিকানা রয়েছে)। সুতরাং এটি সমতা পরীক্ষা করারও যত্ন নেবে না।

আপনার ওভাররাইড সমান () পদ্ধতির অভ্যন্তরে যদি ব্রেকআপপয়েন্ট থাকে তবে তাদের আলাদা আলাদা হ্যাশকোড থাকলে এটি পদক্ষেপ নেবে না। contains()চেকগুলি hashCode()এবং কেবল যদি সেগুলি একই হয় তবে এটি আপনার কল করবেequals() পদ্ধতিটিকে ।

কেন আমরা সমস্ত বালতিতে সাম্যতার জন্য হ্যাশম্যাপ চেক করতে পারি না? সুতরাং হ্যাশকোড () কে ওভাররাইড করার দরকার নেই আমার !!

তারপরে আপনি হ্যাশ ভিত্তিক সংগ্রহের পয়েন্টটি মিস করছেন। নিম্নোক্ত বিবেচনা কর :

Your hashCode() implementation : intObject%9.

নীচে বালতি আকারে সংরক্ষণ করা কীগুলি রয়েছে।

Bucket 1 : 1,10,19,... (in thousands)
Bucket 2 : 2,20,29...
Bucket 3 : 3,21,30,...
...

বলুন, মানচিত্রটিতে কীটি রয়েছে কিনা তা আপনি জানতে চান 10 আপনি কি সমস্ত বালতি অনুসন্ধান করতে চান? অথবা আপনি কি কেবল একটি বালতি অনুসন্ধান করতে চান?

হ্যাশকোডের ভিত্তিতে, আপনি সনাক্ত করতে পারবেন যে যদি 10 উপস্থিত থাকে তবে এটি অবশ্যই বালতি 1 এ উপস্থিত থাকতে হবে So সুতরাং কেবল বালতি 1 অনুসন্ধান করা হবে !!


5
class A {
    int i;
    // Hashing Algorithm
    if even number return 0 else return 1
    // Equals Algorithm,
    if i = this.i return true else false
}
  • পুট ('কী', 'মান') hashCode()বালতি এবং ব্যবহারগুলি নির্ধারণ করতে হ্যাশ মান গণনা করবেequals() মানটি ইতিমধ্যে উপস্থিত রয়েছে কিনা তা জানতে পদ্ধতি করে। তা না হলে এটি যুক্ত করা হবে অন্যথায় এটি বর্তমান মান দিয়ে প্রতিস্থাপিত হবে
  • get ('key' hashCode()) প্রথমে এন্ট্রি (বালতি) equals()সন্ধান করতে এবং এন্ট্রিতে মান সন্ধান করতে ব্যবহৃত হবে

যদি উভয়ই ওভাররাইড করা হয়,

মানচিত্র < >

Map.Entry 1 --> 1,3,5,...
Map.Entry 2 --> 2,4,6,...

সমান যদি ওভাররাইড না হয়

মানচিত্র < >

Map.Entry 1 --> 1,3,5,...,1,3,5,... // Duplicate values as equals not overridden
Map.Entry 2 --> 2,4,6,...,2,4,..

যদি হ্যাশকোড ওভাররাইড না হয়

মানচিত্র < >

Map.Entry 1 --> 1
Map.Entry 2 --> 2
Map.Entry 3 --> 3
Map.Entry 4 --> 1
Map.Entry 5 --> 2
Map.Entry 6 --> 3 // Same values are Stored in different hasCodes violates Contract 1
So on...

হ্যাশকোড সমান চুক্তি

  1. সমান পদ্ধতি অনুসারে দুটি কী একই হ্যাশকোড উত্পন্ন করা উচিত
  2. দুটি হ্যাশকোড উত্পন্ন দুটি কী সমান হতে হবে না (উপরের উদাহরণে সমস্ত সংখ্যারও একই হ্যাশ কোড উত্পন্ন হয়)

4

সমস্ত বাল রঙে একটি বালতিতে বল সংগ্রহ বিবেচনা করুন। আপনার কাজটি সেই বলগুলিকে নিম্নরূপে রঙ করা এবং এটি যথাযথ গেমের জন্য ব্যবহার করা,

টেনিসের জন্য - হলুদ, লাল। ক্রিকেটের জন্য - হোয়াইট

এখন বালতিতে হলুদ, লাল এবং সাদা তিনটি রঙের বল রয়েছে। এবং এখন আপনি রঙটি করেছেন কেবল আপনি জানেন কোন রঙটি কোন গেমের জন্য।

বল বাছাই - হ্যাশিং গেমের জন্য বল নির্বাচন করা - সমান।

আপনি যদি রঙিন করেন এবং কেউ ক্রিকেট বা টেনিস উভয়ের জন্যই বলটি বেছে নেন তারা রঙ পছন্দ করবেন না !!!


4

আমি ব্যাখ্যার দিকে তাকাচ্ছিলাম "যদি আপনি কেবল হ্যাশকোডকে ওভাররাইড করেন তবে আপনি যখন কল করবেন তখন myMap.put(first,someValue)প্রথমে লাগে, এর হ্যাশকোড গণনা করে এটি একটি নির্দিষ্ট বালতিতে সঞ্চয় করে ThenmyMap.put(first,someOtherValue) কারণ তারা সমান এটা প্রতি ম্যাপ ডকুমেন্টেশন যেমন দ্বিতীয় সঙ্গে প্রথম প্রতিস্থাপন করা উচিত (আমাদের সংজ্ঞা অনুসারে) " :

আমি মনে করি দ্বিতীয়বার যখন আমরা যুক্ত করছি myMapতখন এটি 'দ্বিতীয়' অবজেক্টের মতো হওয়া উচিতmyMap.put(second,someOtherValue)


4

1) সাধারণ ভুল নীচের উদাহরণে প্রদর্শিত হয়।

public class Car {

    private String color;

    public Car(String color) {
        this.color = color;
    }

    public boolean equals(Object obj) {
        if(obj==null) return false;
        if (!(obj instanceof Car))
            return false;   
        if (obj == this)
            return true;
        return this.color.equals(((Car) obj).color);
    }

    public static void main(String[] args) {
        Car a1 = new Car("green");
        Car a2 = new Car("red");

        //hashMap stores Car type and its quantity
        HashMap<Car, Integer> m = new HashMap<Car, Integer>();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Car("green")));
    }
}

সবুজ গাড়ি পাওয়া যায় নি

2. হ্যাশকোড দ্বারা সমস্যা ()

সমস্যাটি অ-ওভাররাইড পদ্ধতি দ্বারা সৃষ্ট hashCode()equals()এবং এর মধ্যে চুক্তিটি hashCode()হ'ল:

  1. যদি দুটি বস্তু সমান হয় তবে তাদের অবশ্যই একই হ্যাশ কোড থাকতে হবে।
  2. দুটি বস্তুর যদি একই হ্যাশ কোড থাকে তবে তারা সমান হতে পারে বা নাও পারে।

    public int hashCode(){  
      return this.color.hashCode(); 
    }

4

যখন ব্যবহার করে এটি দরকারী মূল্য অবজেক্টস । নীচে পোর্টল্যান্ড প্যাটার্ন রিপোজিটরির একটি উদ্ধৃত অংশ রয়েছে :

মান অবজেক্টের উদাহরণ হ'ল সংখ্যা, তারিখ, অর্থ এবং স্ট্রিংয়ের মতো জিনিস। সাধারণত, এগুলি হ'ল ছোট বস্তু যা বেশ ব্যাপকভাবে ব্যবহৃত হয়। তাদের পরিচয় তাদের বস্তুর পরিচয়ের পরিবর্তে তাদের রাজ্যের উপর ভিত্তি করে। এইভাবে, আপনার একই ধারণাগত মান অবজেক্টের একাধিক অনুলিপি থাকতে পারে।

সুতরাং আমার কাছে একটি বস্তুর একাধিক অনুলিপি থাকতে পারে যা 16 জানুয়ারী 1998 তারিখের প্রতিনিধিত্ব করে these এই অনুলিপিগুলির মধ্যে একটিও একে অপরের সমান হবে। এর মতো কোনও ছোট্ট অবজেক্টের জন্য, তারিখটি উপস্থাপনের জন্য কোনও একক বস্তুর উপর নির্ভর করার পরিবর্তে প্রায়শই নতুন তৈরি করা এবং এগুলিকে সরানো সহজ।

একটি মান অবজেক্ট সর্বদা জাভাতে। (.HashCode () পাশাপাশি ওভাররাইড করতে মনে রাখবেন))


3

ধরুন আপনার ক্লাস (এ) রয়েছে যা অন্য দুটি (বি) (সি) কে একত্রিত করে, এবং আপনাকে হ্যাশটেবলের ভিতরে (ক) এর উদাহরণ সংরক্ষণ করতে হবে। ডিফল্ট বাস্তবায়ন কেবল উদাহরণগুলি পৃথক করার অনুমতি দেয়, তবে (বি) এবং (সি) দ্বারা নয়। সুতরাং এ এর ​​দুটি উদাহরণ সমান হতে পারে তবে ডিফল্ট আপনাকে সেগুলি সঠিক উপায়ে তুলনা করতে দেয় না।


3

পদ্ধতিগুলি সমান এবং হ্যাশকোডকে বস্তু শ্রেণিতে সংজ্ঞায়িত করা হয়। ডিফল্টরূপে যদি সমান পদ্ধতিটি সত্যটি ফিরে আসে তবে সিস্টেমটি আরও এগিয়ে যাবে এবং হ্যাশ কোডটির মান পরীক্ষা করবে। যদি 2 অবজেক্টের হ্যাশ কোডটিও একই হয় তবে অবজেক্টগুলি একই হিসাবে বিবেচিত হবে। সুতরাং আপনি যদি কেবলমাত্র সমান পদ্ধতিটিকে ওভাররাইড করেন, তবে ওভাররাইড সমান পদ্ধতিটি 2 টি বস্তু সমান হওয়ার ইঙ্গিত দিলেও, সিস্টেমের সংজ্ঞায়িত হ্যাশকোডটি 2 টি বস্তু সমান হতে পারে না not সুতরাং আমাদের পাশাপাশি হ্যাশ কোড ওভাররাইড করা প্রয়োজন।


যদি সমান পদ্ধতিটি সত্য ফিরে আসে তবে হ্যাশকোড চেক করার দরকার নেই। দুটি বস্তুর যদি পৃথক হ্যাশকোড থাকে তবে একটি সমানকে কল না করেই এগুলিকে আলাদা হিসাবে বিবেচনা করতে সক্ষম হওয়া উচিত। আরও, যে তালিকার কোনও কিছুরই নির্দিষ্ট হ্যাশ কোড নেই এমন জ্ঞানটি বোঝায় যে তালিকার কোনও কিছুই সেই হ্যাশ কোডের সাথে নয় বস্তুর সাথে মেলে না। একটি সাধারণ উদাহরণ হিসাবে, যদি কারও কাছে হ্যাশ কোডগুলি সমান সংখ্যক অবজেক্টগুলির একটি তালিকা এবং অবজেক্টের যেখানে তারা বিজোড় সংখ্যাগুলির একটি তালিকা থাকে, তবে হ্যাশ কোডটির একটি সমান সংখ্যা এমন কোনও বস্তু দ্বিতীয় তালিকায় থাকবে না।
সুপারক্যাট

যদি কারওটিতে দুটি এবং এক্স এবং ওয়াই থাকে যার "সমান" পদ্ধতিগুলি মিলেছিল সেগুলি নির্দেশ করে তবে এক্স এর হ্যাশ কোডটি একটি সমান সংখ্যা এবং ওয়াইয়ের হ্যাশ কোডটি একটি বিজোড় সংখ্যা ছিল, উপরে বর্ণিত একটি সংগ্রহ যা উল্লেখ করেছে যে অবজেক্ট ওয়াইয়ের হ্যাশ কোডটি বিজোড় এবং সঞ্চিত ছিল এটি দ্বিতীয় তালিকার মধ্যে এটি এক্স অবজেক্টের জন্য কোনও মিল খুঁজে পাবে না It এটি X এর হ্যাশ কোডটি সমান ছিল এবং দ্বিতীয় তালিকায় সম-সংখ্যাযুক্ত হ্যাশ কোড সহ কোনও অবজেক্ট নেই বলে এটি বিরক্ত করবে না would এক্স এর সাথে মেলে এমন
কিছুর

... অনেকগুলি সংগ্রহগুলি এমন জিনিসগুলির সাথে তুলনা করা এড়াতে পারে যার হ্যাশ কোডগুলি বোঝায় যে তারা সমান হতে পারে না। দুটি বস্তুর যার হ্যাশ কোড অজানা রয়েছে, প্রায়ই তাদের কম্পিউট চেয়ে সরাসরি তুলনা করতে তাদের হ্যাশ কোড দ্রুততর, তাই যে কোন গ্যারান্টি যা অসম হ্যাশ কোড কিন্তু ফিরতি রিপোর্টের trueজন্য equalsম্যাচিং হিসাবে গণ্য করা হবে না। অন্যদিকে, যদি সংগ্রহগুলি লক্ষ্য করে যে জিনিসগুলিতে একই হ্যাশ কোড থাকতে পারে না, তারা সম্ভবত তারা সমান তা লক্ষ্য করবেন না।
ক্যাট

3

জাভাতে সমান এবং হ্যাশকোড পদ্ধতি

এগুলি জাভা.লং.অবজেক্ট ক্লাসের পদ্ধতি যা সমস্ত শ্রেণীর সুপার ক্লাস (কাস্টম ক্লাস এবং জাভা API এ সংজ্ঞায়িত অন্যান্য)।

বাস্তবায়ন:

পাবলিক বুলিয়ান সমান (অবজেক্ট আপত্তি)

পাবলিক ইন্ট হ্যাশকোড ()

এখানে চিত্র বর্ণনা লিখুন

পাবলিক বুলিয়ান সমান (অবজেক্ট আপত্তি)

এই পদ্ধতিটি সহজভাবে পরীক্ষা করে দেখায় যে দুটি বস্তুর রেফারেন্স x এবং y একই বস্তুর উল্লেখ করে। অর্থাত্ এটি x == y যাচাই করে।

এটি প্রতিবিম্বিত: প্রতিবিম্বিত কোনও রেফারেন্স মানের জন্য x, x.equals (x) এর সত্য হওয়া উচিত।

এটি প্রতিসম: কোনও রেফারেন্স মান x এবং y এর জন্য, x.equals (y) এর সত্য হওয়া উচিত যদি কেবলমাত্র y.equals (x) সত্য হয়।

এটি ট্রানজিটিভ: কোনও রেফারেন্স মান x, y এবং z এর জন্য, যদি x.equals (y) সত্য এবং y.equals (z) সত্য প্রত্যাবর্তন করে, তবে x.equals (z) সত্য হওয়া উচিত।

এটি সামঞ্জস্যপূর্ণ: কোনও রেফারেন্স মান x এবং y এর জন্য, x.equals (y) এর একাধিক আহ্বান ধারাবাহিকভাবে সত্য ফিরে আসে বা ধারাবাহিকভাবে মিথ্যা প্রত্যাবর্তন করে, বস্তুর সমান তুলনাতে ব্যবহৃত কোনও তথ্য সংশোধিত না হয়।

কোনও নন-নাল রেফারেন্স মান x এর জন্য x.equals (নাল) এর মিথ্যা প্রত্যাবর্তন করা উচিত।

পাবলিক ইন্ট হ্যাশকোড ()

এই পদ্ধতিটি যার মাধ্যমে এই পদ্ধতিটি চালু রয়েছে তার হ্যাশ কোড মান প্রদান করে। এই পদ্ধতিটি হ্যাশ কোড মানটিকে একটি পূর্ণসংখ্যার হিসাবে ফেরত দেয় এবং হ্যাশবেল, হ্যাশম্যাপ, হ্যাশসেট ইত্যাদির মতো হ্যাশিং ভিত্তিক সংগ্রহের ক্লাসের সুবিধার জন্য সমর্থিত হয় এই পদ্ধতিটি অবশ্যই প্রতিটি শ্রেণিতে ওভাররাইড করা উচিত যা সমান পদ্ধতিটিকে ওভাররাইড করে।

হ্যাশকোডের সাধারণ চুক্তিটি হ'ল:

যখনই এটি কোনও জাভা অ্যাপ্লিকেশন কার্যকর করার সময় একই বস্তুটির উপরে একাধিকবার আহ্বান করা হয়, হ্যাশকোড পদ্ধতিটি ধারাবাহিকভাবে একই পূর্ণসংখ্যাকে ফেরত পাঠাতে হবে, যদি না অবজেক্টের সমান তুলনাতে ব্যবহৃত তথ্য সংশোধিত না হয়।

এই পূর্ণসংখ্যার কোনও প্রয়োগের একটি প্রয়োগ থেকে একই অ্যাপ্লিকেশনটির অন্য প্রয়োগে সামঞ্জস্য থাকা উচিত নয়।

সমান (অবজেক্ট) পদ্ধতি অনুসারে যদি দুটি বস্তু সমান হয়, তবে দুটি বস্তুর প্রত্যেকটিতে হ্যাশকোড পদ্ধতি কল করার ক্ষেত্রে একই সংখ্যার ফলাফল হতে হবে।

সমান (জাভা.লাং.অবজেক্ট) পদ্ধতি অনুসারে যদি দুটি বস্তু অসম হয় তবে দুটি বস্তুর প্রত্যেকটিতে হ্যাশকোড পদ্ধতিটি কল করার ক্ষেত্রে পৃথক পূর্ণসংখ্যার ফলাফল অবশ্যই পাওয়া উচিত। তবে প্রোগ্রামারকে সচেতন হওয়া উচিত যে অসম বস্তুর জন্য স্বতন্ত্র পূর্ণসংখ্যার ফলাফলগুলি হ্যাশটবেলের কার্যকারিতা উন্নত করতে পারে।

সমান অবজেক্টগুলিকে অবশ্যই একই হ্যাশ কোড তৈরি করা উচিত যতক্ষণ না তারা সমান হয় তবে অসম বস্তুগুলির জন্য পৃথক হ্যাশ কোড তৈরি করার প্রয়োজন হয় না।

সম্পদ:

JavaRanch

ছবি


ছবি (ভিডিও লিঙ্ক) ব্যক্তিগত মোডে আছে। এটি দেখার জন্য সর্বজনীন করুন।
উদয়কিরণ পুলিপতি

2

নীচের উদাহরণে, আপনি যদি ব্যক্তি শ্রেণিতে সমান বা হ্যাশকোডের জন্য ওভাররাইড মন্তব্য করেন তবে এই কোডটি টমের ক্রম সন্ধান করতে ব্যর্থ হবে। হ্যাশকোডের ডিফল্ট বাস্তবায়ন হ্যাশট্যাবাল লুকআপগুলিতে ব্যর্থতার কারণ হতে পারে।

আমার নীচে যা আছে তা হল একটি সরলীকৃত কোড যা ব্যক্তি দ্বারা লোকের ক্রমকে টান দেয়। ব্যক্তি হ্যাশটেবলে কী হিসাবে ব্যবহৃত হচ্ছে।

public class Person {
    String name;
    int age;
    String socialSecurityNumber;

    public Person(String name, int age, String socialSecurityNumber) {
        this.name = name;
        this.age = age;
        this.socialSecurityNumber = socialSecurityNumber;
    }

    @Override
    public boolean equals(Object p) {
        //Person is same if social security number is same

        if ((p instanceof Person) && this.socialSecurityNumber.equals(((Person) p).socialSecurityNumber)) {
            return true;
        } else {
            return false;
        }

    }

    @Override
    public int hashCode() {        //I am using a hashing function in String.java instead of writing my own.
        return socialSecurityNumber.hashCode();
    }
}


public class Order {
    String[]  items;

    public void insertOrder(String[]  items)
    {
        this.items=items;
    }

}



import java.util.Hashtable;

public class Main {

    public static void main(String[] args) {

       Person p1=new Person("Tom",32,"548-56-4412");
        Person p2=new Person("Jerry",60,"456-74-4125");
        Person p3=new Person("Sherry",38,"418-55-1235");

        Order order1=new Order();
        order1.insertOrder(new String[]{"mouse","car charger"});

        Order order2=new Order();
        order2.insertOrder(new String[]{"Multi vitamin"});

        Order order3=new Order();
        order3.insertOrder(new String[]{"handbag", "iPod"});

        Hashtable<Person,Order> hashtable=new Hashtable<Person,Order>();
        hashtable.put(p1,order1);
        hashtable.put(p2,order2);
        hashtable.put(p3,order3);

       //The line below will fail if Person class does not override hashCode()
       Order tomOrder= hashtable.get(new Person("Tom", 32, "548-56-4412"));
        for(String item:tomOrder.items)
        {
            System.out.println(item);
        }
    }
}

2

স্ট্রিং ক্লাস এবং র‌্যাপার ক্লাসগুলির বিভিন্ন প্রয়োগ রয়েছে equals()এবংhashCode() অবজেক্ট শ্রেণির চেয়ে পদ্ধতি রয়েছে। অবজেক্ট ক্লাসের সমান () পদ্ধতিটি সামগ্রীর সাথে নয়, বস্তুর উল্লেখগুলির সাথে তুলনা করে। অবজেক্ট শ্রেণির হ্যাশকোড () পদ্ধতিটি প্রতিটি একক বস্তুর জন্য পৃথক হ্যাশকোড উপকরণগুলি একই কিনা তা প্রদান করে।

আপনি মানচিত্র সংগ্রহটি ব্যবহার করার সময় সমস্যাটি দেখা দেয় এবং কীটি স্থির ধরনের, স্ট্রিংবফার / বিল্ডার প্রকারের হয়। যেহেতু তারা স্ট্রিং ক্লাসের বিপরীতে সমান () এবং হ্যাশকোড () ওভাররাইড করে না, তাই সমান () মিথ্যা ফেরত আসবে যখন আপনি দুটি ভিন্ন সামগ্রীর সাথে একই বিষয়বস্তু থাকা সত্ত্বেও দুটি ভিন্ন বস্তুর তুলনা করুন। এটি হ্যাশপ্যাপে একই সামগ্রী কী সংরক্ষণ করবে oring একই বিষয়বস্তু কীগুলি সংরক্ষণ করার অর্থ এটি মানচিত্রের নিয়ম লঙ্ঘন করছে কারণ মানচিত্রটি নকল কীগুলিকে একেবারেই অনুমতি দেয় না। অতএব আপনি আপনার শ্রেণিতে সমান () পাশাপাশি হ্যাশকোড () পদ্ধতিগুলি ওভাররাইড করেন এবং প্রয়োগকরণ সরবরাহ করেন (আইডিই এই পদ্ধতিগুলি উত্পন্ন করতে পারে) যাতে তারা স্ট্রিংয়ের সমান () এবং হ্যাশকোড () এর মতো কাজ করে এবং একই বিষয়বস্তু কীগুলি প্রতিরোধ করে।

সমান () সমেত আপনাকে হ্যাশকোড () পদ্ধতিটি ওভাররাইড করতে হবে কারণ হ্যাশকোড অনুসারে সমান () কাজ করে।

সমান () এর পাশাপাশি হ্যাশকোড () পদ্ধতি ওভাররাইডিং সমান () - হ্যাশকোড () চুক্তি অক্ষত রাখতে সহায়তা করে: "যদি দুটি বস্তু সমান হয় তবে তাদের অবশ্যই একই হ্যাশ কোড থাকতে হবে।"

হ্যাশকোড () এর জন্য আপনার কাস্টম প্রয়োগকরণ কখন লিখতে হবে?

যেমনটি আমরা জানি যে হ্যাশম্যাপের অভ্যন্তরীণ কাজ হ্যাশিংয়ের নীতিতে। কিছু বালতি রয়েছে যেখানে এন্ট্রিসেটগুলি সঞ্চয় করা হয়। আপনার প্রয়োজনীয়তা অনুসারে আপনি হ্যাশকোড () প্রয়োগটি কাস্টমাইজ করুন যাতে একই বিভাগের বিষয়গুলি একই সূচীতে সংরক্ষণ করা যায়। আপনি যখন put(k,v)পদ্ধতিটি ব্যবহার করে মানচিত্র সংগ্রহের ক্ষেত্রে মানগুলি সঞ্চয় করেন , তখন পুট () এর অভ্যন্তরীণ বাস্তবায়ন হয়:

put(k, v){
hash(k);
index=hash & (n-1);
}

মানে, এটি সূচক উত্পন্ন করে এবং নির্দিষ্ট কী বস্তুর হ্যাশকোডের উপর ভিত্তি করে সূচকটি উত্পন্ন হয়। সুতরাং আপনার প্রয়োজনীয়তা অনুসারে এই পদ্ধতিটিকে হ্যাশকোড তৈরি করুন কারণ একই হ্যাশকোড এন্ট্রিসেটগুলি একই বালতি বা সূচীতে সংরক্ষণ করা হবে।

এটাই!


1

hashCode()প্রদত্ত বস্তুর জন্য একটি অনন্য পূর্ণসংখ্যার জন্য পদ্ধতি ব্যবহার করা হয়। এই পূর্ণসংখ্যা বালতি অবস্থান নির্ণয়, যখন এই বস্তু কিছু সংরক্ষণ করা প্রয়োজন জন্য ব্যবহার করা হয় HashTable, HashMapডাটা স্ট্রাকচার মত। ডিফল্টরূপে, অবজেক্টের hashCode()পদ্ধতিটি ফিরে আসে এবং মেমরি ঠিকানার পূর্ণসংখ্যার উপস্থাপনা যেখানে বস্তু সঞ্চিত থাকে।

hashCode()বস্তুর পদ্ধতি যখন আমরা তাদের একটি মধ্যে সন্নিবেশ ব্যবহার করা হয় HashTable, HashMapবা HashSetHashTablesরেফারেন্সের জন্য উইকিপিডিয়া.অর্গ সম্পর্কে আরও

মানচিত্রের ডেটা স্ট্রাকচারে কোনও প্রবেশ সন্নিবেশ করতে, আমাদের কী এবং মান উভয়ই দরকার। যদি কী এবং মানগুলি উভয়ই ডেটা সংজ্ঞায়িত করে থাকে তবে কীটির মান নির্ধারণ করা hashCode()হবে যে কোনওভাবে অভ্যন্তরীণভাবে সংরক্ষণ করতে হবে। মানচিত্র থেকেও যখন বস্তুটি অনুসন্ধান করার প্রয়োজন হবে তখন কীটির হ্যাশ কোডটি নির্ধারণ করা হবে যে কোন বস্তুর সন্ধান করতে হবে।

হ্যাশ কোডটি কেবল অভ্যন্তরীণভাবে নির্দিষ্ট "অঞ্চল" (বা তালিকা, বালতি ইত্যাদি) নির্দেশ করে। যেহেতু বিভিন্ন মূল বিষয়গুলির সম্ভাব্যভাবে একই হ্যাশ কোড থাকতে পারে, তাই হ্যাশ কোডটি নিজেই কোনও সঠিক গানের গ্যারান্টি নেই। HashTableতারপর এই এলাকা (একই হ্যাশ কোড সহ সমস্ত কী) iterates এবং কী এর ব্যবহার equals()সঠিক কী খুঁজে পেতে পদ্ধতি। একবার ডান কীটি পাওয়া গেলে, সেই কীটির জন্য সঞ্চিত অবজেক্টটি ফিরে আসবে।

সুতরাং, যেমন আমরা দেখতে পাচ্ছি, স্টোর করার সময় hashCode()এবং equals()একটিতে অবজেক্টগুলি সন্ধান করার সময় এবং পদ্ধতির একটি সংমিশ্রণ ব্যবহৃত হয় HashTable

মন্তব্য:

  1. উত্পাদনের জন্য hashCode()এবং equals()উভয়ের জন্য সর্বদা অবজেক্টের একই বৈশিষ্ট্যগুলি ব্যবহার করুন । আমাদের ক্ষেত্রে যেমন আমরা কর্মচারী আইডি ব্যবহার করেছি।

  2. equals() অবশ্যই সামঞ্জস্য হতে হবে (যদি বস্তুগুলি সংশোধিত না হয় তবে অবশ্যই এটির একই মানটি ফেরত যেতে হবে)।

  3. যখনই a.equals(b), তখন a.hashCode()অবশ্যই একই হতে হবে b.hashCode()

  4. আপনি যদি একটিটিকে ওভাররাইড করে থাকেন তবে আপনার অন্যটিকে ওভাররাইড করা উচিত।

http://parameshk.blogspot.in/2014/10/examples-of-comparable-comporator.html


hashCode()প্রতিটি বস্তুর জন্য একটি অনন্য পূর্ণসংখ্যার ফেরত ব্যবহার করা হয় না। যে অসম্ভব. চতুর্থ অনুচ্ছেদের দ্বিতীয় বাক্যে আপনি এটিকে নিজের সাথে বিবাদ করেছেন।
লার্নের মারকুইস

@ ইজেপি, বেশিরভাগ সময় হ্যাঁকোড () দুটি পৃথক পৃথক বস্তুর জন্য স্বতন্ত্র পূর্ণসংখ্যার ফিরিয়ে দেবে। তবে দুটি ভিন্ন অবজেক্টের জন্য হ্যাককোডের সংঘর্ষ হওয়ার সম্ভাবনা রয়েছে, এই ধারণাকে হ্যাশকোড সংঘাত বলে । দয়া করে রেফার করুন: tech.queryhome.com/96931/…
পরমেশ কোরাকাকুতি

1

আইএমএইচও, এটি নিয়ম অনুসারে বলে - যদি দুটি বস্তু সমান হয় তবে তাদের একই হ্যাশ থাকা উচিত, সমান বস্তুগুলির সমান হ্যাশ মান তৈরি করা উচিত।

উপরে প্রদত্ত, অবজেক্টে ডিফল্ট সমান () হল == যা ঠিকানার সাথে তুলনা করে, হ্যাশকোড () ঠিকানাকে পূর্ণসংখ্যায় (আসল ঠিকানায় হ্যাশ) প্রদান করে যা আবার স্বতন্ত্র অবজেক্টের জন্য স্বতন্ত্র।

যদি আপনাকে হ্যাশ ভিত্তিক সংগ্রহগুলিতে কাস্টম অবজেক্টগুলি ব্যবহার করতে হয়, আপনার উভয় সমান () এবং হ্যাশকোড () দুটি ওভাররাইড করতে হবে, উদাহরণস্বরূপ যদি আমি কর্মচারী অবজেক্টগুলির হ্যাশসেট বজায় রাখতে চাই তবে আমি যদি শক্তিশালী হ্যাশকোড ব্যবহার না করি এবং সমান আমি দুটি পৃথক কর্মচারী অবজেক্টগুলিকে ওভাররাইড করতে পারি, যখন আমি বয়সটি হ্যাশকোড () হিসাবে ব্যবহার করি তখনই এটি ঘটতে পারে, তবে আমার অনন্য মানটি ব্যবহার করা উচিত যা কর্মচারী আইডি হতে পারে।


1

আপনাকে সদৃশ বস্তুগুলি পরীক্ষা করতে সহায়তা করতে আমাদের একটি কাস্টম সমান এবং হ্যাশকোড দরকার।

যেহেতু হ্যাশকোড একটি বর্ণমালার চাবি না করে একটি সংখ্যা ব্যবহার করে কোনও বস্তু পুনরুদ্ধার করতে সর্বদা দ্রুত তার নম্বর দ্রুত ফেরত দেয়। এটা কিভাবে করবে? ধরা যাক আমরা কিছু মান পাস করে একটি নতুন অবজেক্ট তৈরি করেছি যা ইতিমধ্যে কিছু অন্য অবজেক্টে উপলব্ধ। এখন নতুন অবজেক্টটি অন্য অবজেক্টের মতো একই হ্যাশ মান প্রদান করবে কারণ পাস করা মান একই। একই হ্যাশ মানটি ফিরে আসার পরে, জেভিএম প্রতিবার একই মেমরি ঠিকানায় যাবে এবং যদি একই হ্যাশ মানের জন্য একাধিক অবজেক্ট উপস্থিত থাকে তবে এটি সঠিক অবজেক্টটি সনাক্ত করতে সমান () পদ্ধতি ব্যবহার করবে।


1

আপনি যখন মানচিত্রে কী হিসাবে আপনার কাস্টম অবজেক্টটি সংরক্ষণ এবং পুনরুদ্ধার করতে চান, তখন আপনার কাস্টম অবজেক্টে সর্বদা সমান এবং হ্যাশকোডকে ওভাররাইড করা উচিত। উদাহরণ:

Person p1 = new Person("A",23);
Person p2 = new Person("A",23);
HashMap map = new HashMap();
map.put(p1,"value 1");
map.put(p2,"value 2");

এখানে পি 1 এবং পি 2 কেবলমাত্র একটি অবজেক্ট হিসাবে বিবেচনা করবে এবং mapআকার সমান হওয়ায় কেবল 1 হবে।


1
public class Employee {

    private int empId;
    private String empName;

    public Employee(int empId, String empName) {
        super();
        this.empId = empId;
        this.empName = empName;
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    @Override
    public String toString() {
        return "Employee [empId=" + empId + ", empName=" + empName + "]";
    }

    @Override
    public int hashCode() {
        return empId + empName.hashCode();
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }
        if (!(this instanceof Employee)) {
            return false;
        }
        Employee emp = (Employee) obj;
        return this.getEmpId() == emp.getEmpId() && this.getEmpName().equals(emp.getEmpName());
    }

}

পরীক্ষা ক্লাস

public class Test {

    public static void main(String[] args) {
        Employee emp1 = new Employee(101,"Manash");
        Employee emp2 = new Employee(101,"Manash");
        Employee emp3 = new Employee(103,"Ranjan");
        System.out.println(emp1.hashCode());
        System.out.println(emp2.hashCode());
        System.out.println(emp1.equals(emp2));
        System.out.println(emp1.equals(emp3));
    }

}

অবজেক্ট ক্লাসে সমান (অবজেক্ট আপত্তি) ঠিকানার তুলনা তুলনা করতে ব্যবহৃত হয় কেন টেস্ট ক্লাসে যখন আপনি দুটি বস্তুর তুলনা করেন তবে পদ্ধতিটি মিথ্যা প্রদানের সমান হয় তবে আমরা যখন হ্যাশকোড () কে ওভাররাইড করি তখন এটি সামগ্রীটিকে তুলনা করতে এবং সঠিক ফলাফল দিতে পারে give


এবং টেস্ট ক্লাসটি আমি নীচের প্রোগ্রামে যুক্ত করেছি।
মানশ রঞ্জন ডাকুয়া

অবজেক্ট ক্লাসে সমান (অবজেক্ট আপত্তি) ঠিকানার তুলনা তুলনা করতে ব্যবহৃত হয় কেন টেস্ট ক্লাসে যখন আপনি দুটি বস্তুর তুলনা করেন তবে মিথ্যা দেওয়ার পদ্ধতি সমান হয় তবে আমরা যখন হ্যাশকোড () কে ওভাররাইড করি তখন এটি সামগ্রীর তুলনা করতে পারে এবং সঠিক ফলাফল দেয়।
মনশ রঞ্জন ডাকুয়া

1
আপনি নিজের উত্তর যুক্ত করতে এই উত্তরটির ঠিক নীচে সম্পাদনা লিঙ্কটি ব্যবহার করতে পারেন .. দয়া করে দুটি অসম্পূর্ণ হিসাবে কোনও উত্তর যুক্ত করবেন না
সুরজ রাও

1

আপনি যদি ওভাররাইড করেন equals()এবং না করেন hashcode()তবে আপনি বা অন্য কেউ এই শ্রেণীর ধরণটি হ্যাশ সংগ্রহের মতো ব্যবহার না করলে আপনি কোনও সমস্যা খুঁজে পাবেন না HashSet। আমার আগে লোকেরা নথিভুক্ত তত্ত্বটি একাধিকবার পরিষ্কারভাবে ব্যাখ্যা করেছে, আমি খুব সহজ উদাহরণ দেওয়ার জন্য এখানে আছি।

এমন একটি শ্রেণী বিবেচনা করুন যার equals()প্রয়োজন অনুসারে কিছু অনুকূলিতকরণ করা প্রয়োজন: -

    public class Rishav {

        private String rshv;

        public Rishav(String rshv) {
            this.rshv = rshv;
        }

        /**
        * @return the rshv
        */
        public String getRshv() {
            return rshv;
        }

        /**
        * @param rshv the rshv to set
        */
        public void setRshv(String rshv) {
            this.rshv = rshv;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Rishav) {
                obj = (Rishav) obj;
                if (this.rshv.equals(((Rishav) obj).getRshv())) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }

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

    }

এখন এই প্রধান শ্রেণীর বিবেচনা করুন: -

    import java.util.HashSet;
    import java.util.Set;

    public class TestRishav {

        public static void main(String[] args) {
            Rishav rA = new Rishav("rishav");
            Rishav rB = new Rishav("rishav");
            System.out.println(rA.equals(rB));
            System.out.println("-----------------------------------");

            Set<Rishav> hashed = new HashSet<>();
            hashed.add(rA);
            System.out.println(hashed.contains(rB));
            System.out.println("-----------------------------------");

            hashed.add(rB);
            System.out.println(hashed.size());
        }

    }

এটি নিম্নলিখিত আউটপুট প্রদান করবে: -

    true
    -----------------------------------
    true
    -----------------------------------
    1

আমি ফলাফল নিয়ে খুশি। তবে আমি যদি ওভাররাইড না করে থাকি তবে hashCode()এটি দুঃস্বপ্নের কারণ হয়ে দাঁড়ায় কারণ Rishavএকই সদস্যের বিষয়বস্তুযুক্ত বস্তুগুলিকে আর অনন্য হিসাবে বিবেচনা করা hashCodeহবে না, ডিফল্ট আচরণের দ্বারা উত্পন্ন হিসাবে, এখানে আউটপুট হবে: -

    true
    -----------------------------------
    false
    -----------------------------------
    2

0

উভয় পদ্ধতি অবজেক্ট শ্রেণিতে সংজ্ঞায়িত করা হয়। এবং উভয়ই এর সহজ বাস্তবায়নে রয়েছে। সুতরাং যখন আপনার প্রয়োজন হয় আপনি এই পদ্ধতিগুলিতে আরও কিছু বাস্তবায়ন যুক্ত করতে চান তবে আপনার ক্লাসে আপনার ওভাররাইড হবে।

উদাহরণস্বরূপ: বস্তুতে সমান () পদ্ধতিটি কেবলমাত্র রেফারেন্সে তার সমতা পরীক্ষা করে। সুতরাং আপনার যদি তার রাজ্যের তুলনা করারও প্রয়োজন হয় তবে আপনি স্ট্রিং ক্লাসে যেমন এটি করা হয় তেমন ওভাররাইড করতে পারেন।


-3

বাহ - "আপনাকে অবশ্যই প্রতিটি শ্রেণিতে হ্যাশকোড () এর ওভাররাইড করতে হবে যা সমান () এর চেয়ে ওভাররাইড করে।"

[কার্যকর জাভা থেকে, জোশুয়া ব্লচ দ্বারা?]

এটি কি ভুল পথে নয়? ওভাররাইডিং হ্যাশকোড সম্ভবত ইঙ্গিত দেয় আপনি হ্যাশ-কী শ্রেণি লিখছেন, তবে ওভাররাইডিং সমান অবশ্যই তা করে না। অনেকগুলি শ্রেণি রয়েছে যা হ্যাশ-কী হিসাবে ব্যবহৃত হয় না, তবে অন্য কোনও কারণে যৌক্তিক-সাম্যতা-পরীক্ষার পদ্ধতি চায়। আপনি যদি এর জন্য "সমান" চয়ন করেন তবে আপনাকে এই নিয়মের অত্যধিক সংবেদনশীল প্রয়োগের মাধ্যমে একটি হ্যাশকোড বাস্তবায়ন লিখতে বাধ্য করা যেতে পারে। যা কিছু অর্জন করে তা হ'ল কোডবেসে অনির্ধারিত কোড যুক্ত করা হয়, ভবিষ্যতে কাউকে ট্রিপ করার অপেক্ষায় evil এছাড়াও কোড লেখার দরকার নেই এটি বিরোধী। এটি ঠিক ভুল (এবং একটি উত্পন্ন আদর্শ সম্ভবত আপনার হাতের তৈরি কার্যের সমতুল্য নয়) omp

কী হিসাবে তাদের কী হিসাবে ব্যবহার করার জন্য লিখিত বস্তুগুলির একটি ইন্টারফেস আদেশ করা উচিত ছিল? নির্বিশেষে, অবজেক্টটি কখনই ডিফল্ট হ্যাশকোড () এবং সমান () imho সরবরাহ করা উচিত নয়। এটি সম্ভবত অনেক ভাঙ্গা হ্যাশ সংগ্রহকে উত্সাহিত করেছে।

তবে যাইহোক, আমি মনে করি "নিয়ম" সামনে লেখা আছে। এরই মধ্যে, আমি সমতা পরীক্ষার পদ্ধতির জন্য "সমান" ব্যবহার করা এড়িয়ে চলব :-(

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.