CodeGym /مدونة جافا /Random-AR /جافا هاش كود ()
John Squirrels
مستوى
San Francisco

جافا هاش كود ()

نشرت في المجموعة

مبدأ التجزئة

أولاً، قبل أن نحدد كود تجزئة جافا، نحتاج إلى فهم ما هو التجزئة وما الغرض منه. التجزئة هي عملية تطبيق دالة التجزئة على بعض البيانات. وظيفة التجزئة هي مجرد وظيفة رياضية. لا تقلق بشأن هذا! "الرياضيات" لا تعني دائمًا "معقدة". هنا يعني فقط أن لدينا بعض البيانات وقاعدة معينة تقوم بتعيين البيانات في مجموعة من الأحرف (الكود). على سبيل المثال، يمكن أن يكون التشفير الست عشري. لدينا بعض البيانات من أي حجم عند الإدخال، ونطبق دالة التجزئة عليها. عند الإخراج، نحصل على بيانات ذات حجم ثابت، على سبيل المثال، 32 حرفًا. عادةً ما يقوم هذا النوع من الوظائف بتحويل جزء كبير من البيانات إلى قيمة عددية صغيرة. تسمى نتيجة عمل هذه الوظيفة رمز التجزئة. تُستخدم وظائف التجزئة على نطاق واسع في التشفير، وفي بعض المجالات الأخرى أيضًا. يمكن أن تكون وظائف التجزئة مختلفة، ولكن جميعها لها خصائص معينة:
  • كائن معين له رمز تجزئة معين.
  • إذا كان هناك كائنان متساويان، فإن رموز التجزئة الخاصة بهما هي نفسها. والعكس ليس صحيحا.
  • إذا كانت رموز التجزئة مختلفة، فإن الكائنات ليست متساوية بالتأكيد.
  • قد تحتوي الكائنات المختلفة على نفس رمز التجزئة. ومع ذلك، فهو حدث غير محتمل للغاية. عند هذه النقطة، لدينا تصادم، حالة يمكن أن نفقد فيها البيانات.
تعمل وظيفة التجزئة "المناسبة" على تقليل احتمالية الاصطدامات.

كود التجزئة في جافا

في Java، عادةً ما تكون وظيفة التجزئة متصلة بطريقة hashCode() . على وجه التحديد، نتيجة تطبيق دالة التجزئة على كائن ما هي رمز التجزئة. يحتوي كل كائن Java على رمز تجزئة. بشكل عام رمز التجزئة هو رقم يتم حسابه بواسطة طريقة hashCode() الخاصة بالفئة Object. عادة، يتجاوز المبرمجون هذه الطريقة لكائناتهم وكذلك المتعلقة بـ hashCode() وهي طريقة يساوي() لمعالجة أكثر كفاءة لبيانات محددة. تقوم طريقة hashCode () بإرجاع قيمة int (4 بايت)، وهي تمثيل رقمي للكائن. يتم استخدام رمز التجزئة هذا، على سبيل المثال، من خلال المجموعات لتخزين البيانات بشكل أكثر كفاءة، وبالتالي الوصول إليها بشكل أسرع. بشكل افتراضي، تقوم الدالة hashCode() لكائن ما بإرجاع رقم خلية الذاكرة حيث تم تخزين الكائن. لذلك، إذا لم يتم إجراء أي تغييرات على رمز التطبيق، فيجب أن تقوم الدالة بإرجاع نفس القيمة. إذا تغير الرمز قليلاً، تتغير قيمة رمز التجزئة أيضًا. ما هو رمز التجزئة المستخدم في جافا؟ بادئ ذي بدء، تساعد رموز تجزئة Java البرامج على العمل بشكل أسرع. على سبيل المثال، إذا قمنا بمقارنة كائنين o1ومن o2نوع ما، فإن العملية o1.equals(o2)تستغرق وقتًا أطول بحوالي 20 مرة من o1.hashCode() == o2.hashCode().

جافا يساوي ()

في الفئة الأصل Object، بالإضافة إلى طريقة hashCode() ، هناك أيضًا يساوي() ، وهي الوظيفة المستخدمة للتحقق من مساواة كائنين. يقوم التنفيذ الافتراضي لهذه الوظيفة ببساطة بالتحقق من الروابط بين كائنين للتأكد من تكافؤهما. يساوي () و hashCode () عقدهما، لذا إذا تجاوزت أحدهما، فيجب عليك تجاوز الآخر، حتى لا تكسر هذا العقد.

تنفيذ طريقة hashCode ().

مثال

لنقم بإنشاء فئة Character بحقل واحد - name . بعد ذلك، نقوم بإنشاء كائنين من فئة الحرف ، Character1 و Character2 ونضع لهما نفس الاسم. إذا استخدمنا hashCode() و equals() الافتراضيين لفئة Object ، فسنحصل بالتأكيد على كائنات مختلفة وليست متساوية. هذه هي الطريقة التي يعمل بها رمز التجزئة في Java. سيكون لها رموز تجزئة مختلفة لأنها موجودة في خلايا ذاكرة مختلفة وستكون نتيجة عملية يساوي () خاطئة.
import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
نتيجة تشغيل البرنامج:

Arnold
1595428806
Arnold
1072408673
false
الرقمان المكونان من 10 أرقام في وحدة التحكم هما رموز تجزئة. ماذا لو أردنا الحصول على كائنات متساوية إذا كانت لها نفس الأسماء؟ ماذا علينا ان نفعل؟ الجواب: يجب علينا تجاوز أساليب hashCode() و equals() لفئة الكائن لفئة الأحرف الخاصة بنا . يمكننا القيام بذلك تلقائيًا في IDEA IDE، فقط اضغط على alt + Insert على لوحة المفاتيح واختر Generate ->equals() و hashCode() . ما هو Java hashCode () - 2في حالة مثالنا لدينا الكود التالي:
import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Character)) return false;

        Character character = (Character) o;

        return getName() != null ? getName().equals(character.getName()) : character.getName() == null;
    }

    @Override
    public int hashCode() {
        return getName() != null ? getName().hashCode() : 0;
    }

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
نتيجة تشغيل هذا الكود:

Arnold
1969563338
Arnold
1969563338
true
والآن يعرّف البرنامج الكائنات لدينا على أنها متساوية ولها نفس رموز التجزئة.

مثال على كود تجزئة جافا:

hashCode () الخاص بك ويساوي ()

يمكنك أيضًا إنشاء عمليات تحقيق متساوية () و hashCode () الخاصة بك ، ولكن كن حذرًا وتذكر تقليل تصادمات رمز التجزئة. فيما يلي مثال على أساليب hashCode() و equals() الخاصة بنا في فئة الطالب :
import java.util.Date;

public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }
//Java hashcode example
   @Override
   public int hashCode(){
       //TODO: check for nulls
       //return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
والفئة الرئيسية لتوضيح أعمالهم:
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;

public class Main {
   static HashMap<Student, Integer> cache = new HashMap<Student, Integer>(); // <person, targetPriority>

   public static void main(String[] args) {
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student sarah2 = new Student("Sarah","Connor", "Jane", new Date(1970, 01-1, 01));
       Student sarah3 = new Student("Sarah","Connor", "Jane", new Date(1959, 02-1, 28)); // date not exists
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       Student johnny = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       System.out.println(john.hashCode());
       System.out.println(johnny.hashCode());
       System.out.println(sarah1.hashCode());
       System.out.println();
       cache.put(sarah1, 1);
       cache.put(sarah2, 2);
       cache.put(sarah3, 3);
       System.out.println(new Date(sarah1.birthday));
       System.out.println();
       cache.put(john, 5);
       System.out.println(cache.get(john));
       System.out.println(cache.get(johnny));
       cache.put(johnny, 7);
       System.out.println(cache.get(john));
       System.out.println(cache.get(johnny));
   }
}

ما هو رمز التجزئة المستخدم؟

بادئ ذي بدء، تساعد رموز التجزئة البرامج على العمل بشكل أسرع. على سبيل المثال، إذا قارنا كائنين o1ومن o2نوع ما، فستستغرق العملية o1.equals(o2)وقتًا أطول بحوالي 20 مرة من o1.hashCode() == o2.hashCode(). يعتمد مبدأ التجزئة في Java على بعض المجموعات الشائعة، مثل HashMap و HashSet و HashTable .

خاتمة

يحتوي كل كائن Java على أساليب hashCode () و equals () الموروثة من فئة الكائن . للحصول على آلية جيدة للمساواة في العمل، من الأفضل أن تتجاوز أساليب hashcode() و equals() للفصول الدراسية الخاصة بك. يؤدي استخدام رموز التجزئة إلى تشغيل البرامج بشكل أسرع.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION