Преди всичко, преди да дефинираме хеш codeа на Java, трябва да разберем Howво е хеширане и за Howво служи. Хеширането е процес на прилагане на хеш функция към някои данни. Хеш функцията е просто математическа функция. Не се тревожете за това! „Математически“ не винаги означава „сложен“. Тук това означава само, че имаме някои данни и определено правило, което картографира данните в набор от знаци (code). Например, може да е шестнадесетичен шифър. Имаме някои данни с произволен размер на входа и прилагаме хеш функция към тях. На изхода получаваме данни с фиксиран размер, да речем, 32 знака. Обикновено този вид функция преобразува голяма част от данни в малка целочислена стойност. Резултатът от работата на тази функция се нарича хеш code. Хеш функциите се използват широко в криптографията, Howто и в някои други области. Хеш функциите могат да бъдат различни,
Конкретен обект има конкретен хешcode.
Ако два обекта са еднакви, техните хеш codeове са еднакви. Обратното не е вярно.
Ако хеш codeовете са различни, тогава обектите не са равни със сигурност.
Различни обекти могат да имат един и същ хеш code. Това обаче е много малко вероятно събитие. В този момент имаме сблъсък, ситуация, при която можем да загубим данни.
„Правилната“ хеш функция минимизира вероятността от сблъсъци.
Hashcode в Java
В Java хеш функцията обикновено е свързана с метода hashCode() . По-точно, резултатът от прилагането на хеш функция към обект е хешcode. Всеки Java обект има хеш code. Като цяло Hash Code е число, изчислено чрез метода hashCode() на Objectкласа. Обикновено програмистите заменят този метод за своите обекти, Howто и свързания с hashCode() метода equals() за по-ефективна обработка на конкретни данни. Методът hashCode() връща int (4 byteа) стойност, която е цифрово представяне на обекта. Този хешcode се използва например от колекции за по-ефективно съхранение на данни и съответно по-бърз достъп до тях. По подразбиране hashCode()функцията за обект връща номера на клетката от паметта, където се съхранява обектът. Следователно, ако не се правят промени в codeа на приложението, тогава функцията трябва да върне същата стойност. Ако codeът се промени леко, стойността на хеш-codeа също се променя. За Howво се използва хешcodeът в Java? На първо място, Java hashcodes помагат на програмите да работят по-бързо. Например, ако сравним два обекта o1и o2от няHowъв тип, операцията o1.equals(o2)отнема около 20 пъти повече време от o1.hashCode() == o2.hashCode().
Java е равно на ()
В родителския клас Object, заедно с метода hashCode() , има също equals() , функцията, която се използва за проверка на equalsството на два обекта. Изпълнението по подразбиране на тази функция просто проверява връзките на два обекта за тяхната еквивалентност. equals() и hashCode() имат свой договор, така че ако замените един от тях, трябва да замените другия, за да не нарушите този договор.
Внедряване на метода hashCode().
Пример
Нека създадем клас Character с едно поле — име . След това създаваме два обекта от класа Character , character1 и character2 и им задаваме едно и също име. Ако използваме по подразбиране hashCode() и equals() на класа Object , определено ще получим различни, не еднакви обекти. Ето How работи hashcode в Java. Те ще имат различни хешcodeове, тъй като са в различни клетки на паметта и резултатът от операцията equals() ще бъде false.
Две 10-цифрени числа в конзолата са хеш codeове. Какво ще стане, ако искаме да имаме равни обекти, ако имат еднакви имена? Какво да правим? Отговорът: трябва да заменим методите hashCode() и equals() на класа Object за нашия клас Character . Можем да го направим автоматично в IDEA IDE, просто натиснете alt + insert на клавиатурата и изберете Generate -> equals() и hashCode() . В случая с нашия пример имаме следния code:
Така че сега програмата идентифицира нашите обекти като равни и те имат еднакви хеш codeове.
Пример за хаш code на Java:
Ваш собствен hashCode() и equals()
Можете също така да създадете свои собствени реализации на equals() и hashCode() , но бъдете внимателни и не забравяйте да минимизирате сблъсъците с хешcode. Ето пример за нашите собствени методи hashCode() и equals() в класа Student :
importjava.util.Date;publicclassStudent{String surname;String name;String secondName;Long birthday;// Long instead of long is used by Gson/Jackson json parsers and various orm databasespublicStudent(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@OverridepublicinthashCode(){//TODO: check for nulls//return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());return(surname + name + secondName + birthday).hashCode();}@Overridepublicbooleanequals(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));}}
И основният клас, за да демонстрира своята работа:
importjava.util.Date;importjava.util.HashMap;importjava.util.Hashtable;publicclassMain{staticHashMap<Student,Integer> cache =newHashMap<Student,Integer>();// <person, targetPriority>publicstaticvoidmain(String[] args){Student sarah1 =newStudent("Sarah","Connor","Jane",null);Student sarah2 =newStudent("Sarah","Connor","Jane",newDate(1970,01-1,01));Student sarah3 =newStudent("Sarah","Connor","Jane",newDate(1959,02-1,28));// date not existsStudent john =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsStudent johnny =newStudent("John","Connor","Kyle",newDate(1985,02-1,28));// date not existsSystem.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(newDate(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));}}
За Howво се използва хешcodeът?
На първо място хешcodeовете помагат на програмите да работят по-бързо. Например, ако сравним два обекта o1и o2от няHowъв тип, операцията o1.equals(o2)отнема около 20 пъти повече време от o1.hashCode() == o2.hashCode(). В Java принципът на хеширане стои зад някои популярни колекции, като HashMap , HashSet и HashTable .
Заключение
Всеки Java обект има методите hashCode() и equals(), наследени от класа Object . За да получите добър работещ механизъм за equalsство, по-добре отменете методите hashcode() и equals() за вашите собствени класове. Използването на хешcodeове кара програмите да работят по-бързо.