CodeGym /وبلاگ جاوا /Random-FA /هش کد جاوا ()
John Squirrels
مرحله
San Francisco

هش کد جاوا ()

در گروه منتشر شد

اصل هش

اول از همه، قبل از تعریف هش کد جاوا، باید بدانیم که هش کردن چیست و برای چیست. هش کردن فرآیند اعمال یک تابع هش برای برخی از داده ها است. یک تابع هش فقط یک تابع ریاضی است. نگران این نباش! "ریاضی" همیشه به معنای "پیچیده" نیست. در اینجا فقط به این معنی است که ما مقداری داده و قانون خاصی داریم که داده ها را به مجموعه ای از کاراکترها (کد) نگاشت می کند. به عنوان مثال، می تواند یک رمز هگزادسیمال باشد. مقداری داده با هر اندازه ای در ورودی داریم و یک تابع هش برای آن اعمال می کنیم. در خروجی، یک داده با اندازه ثابت، مثلاً 32 کاراکتر، دریافت می کنیم. معمولاً این نوع تابع، یک قطعه بزرگ از داده را به یک مقدار صحیح کوچک تبدیل می کند. نتیجه کار این تابع کد هش نامیده می شود. توابع هش به طور گسترده در رمزنگاری و برخی مناطق دیگر استفاده می شود. توابع هش می توانند متفاوت باشند، اما همه آنها ویژگی های خاصی دارند:
  • یک شی خاص دارای هش کد خاصی است.
  • اگر دو شی با هم برابر باشند، کد هش آنها یکسان است. عکس این قضیه درست نیست.
  • اگر کدهای هش متفاوت باشند، پس اشیا به طور قطع برابر نیستند.
  • ممکن است اشیاء مختلف کد هش یکسانی داشته باشند. با این حال، این یک رویداد بسیار بعید است. در این مرحله، ما یک برخورد داریم، موقعیتی که می توانیم داده ها را از دست بدهیم.
تابع هش "مناسب" احتمال برخورد را به حداقل می رساند.

هش کد در جاوا

در جاوا تابع هش معمولاً به متد ()hashCode متصل است . دقیقاً، نتیجه اعمال یک تابع هش به یک شیء یک کد هش است. هر شی جاوا یک کد هش دارد. به طور کلی کد هش عددی است که توسط متد hashCode() کلاس محاسبه می شود Object. معمولاً برنامه نویسان این روش را برای اشیاء خود و همچنین مربوط به ()hashCode متد () quals را برای پردازش کارآمدتر داده های خاص نادیده می گیرند. متد hashCode() مقدار int (4 بایت) را برمی گرداند که نمایش عددی شی است. این کد هش، به عنوان مثال، توسط مجموعه ها برای ذخیره سازی کارآمدتر داده ها و بر این اساس، دسترسی سریع تر به آنها استفاده می شود. به‌طور پیش‌فرض، تابع hashCode() برای یک شی، تعداد سلول حافظه را که در آن شی ذخیره می‌شود، برمی‌گرداند. بنابراین، اگر هیچ تغییری در کد برنامه ایجاد نشود، تابع باید همان مقدار را برگرداند. اگر کد کمی تغییر کند، مقدار هش کد نیز تغییر می کند. هش کد مورد استفاده در جاوا برای چیست؟ اول از همه کدهای هش جاوا به برنامه ها کمک می کند تا سریعتر اجرا شوند. o1به عنوان مثال، اگر دو شی را با هم مقایسه کنیم o2، عملیات o1.equals(o2)حدود 20 برابر بیشتر از o1.hashCode() == o2.hashCode().

جاوا برابر است()

در کلاس والد Object، همراه با متد ()hashCode ، تابعی که برای بررسی برابری دو شی استفاده می‌شود، برابری () نیز وجود دارد . اجرای پیش فرض این تابع به سادگی پیوندهای دو شیء را برای هم ارزی آنها بررسی می کند. ()quals و hashCode() قرارداد خود را دارند، بنابراین اگر یکی از آنها را لغو کردید، باید دیگری را لغو کنید تا این قرارداد شکسته نشود.

پیاده سازی متد ()hashCode

مثال

بیایید یک کاراکتر کلاس با یک فیلد ایجاد کنیم - نام . پس از آن، دو شی از کلاس Character ، character1 و character2 ایجاد می کنیم و آنها را به یک نام می گذاریم. اگر از hashCode() و equals() پیش‌فرض کلاس Object استفاده کنیم ، قطعاً اشیاء متفاوت و نه مساوی دریافت خواهیم کرد. هش کد در جاوا اینگونه کار می‌کند. آنها کدهای هش متفاوتی خواهند داشت زیرا در سلول های حافظه متفاوتی قرار دارند و نتیجه عملیات ()Equals نادرست خواهد بود.
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() کلاس Object را برای کلاس Character خود نادیده بگیریم . می‌توانیم این کار را به‌طور خودکار در IDEA IDE انجام دهیم، فقط alt + insert را روی صفحه‌کلید خود فشار دهید و Generate ->quals() و 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() در کلاس Student آورده شده است :
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() زمان می برد. در جاوا اصل هش کردن پشت برخی از مجموعه های محبوب مانند HashMap ، HashSet و HashTable قرار دارد .

نتیجه

هر شی جاوا دارای متدهای hashCode() و equals() است که از کلاس Object به ارث برده شده است. برای به دست آوردن یک مکانیسم برابری کاری خوب، بهتر است متدهای hashcode() و quals() را برای کلاس های خود نادیده بگیرید. استفاده از کدهای هش باعث می شود برنامه ها سریعتر اجرا شوند.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION