John Squirrels
Ниво
San Francisco

Java hashCode()

Публикувано в групата

Хеш принцип

Преди всичко, преди да дефинираме хеш 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.

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-цифрени числа в конзолата са хеш codeове. Какво ще стане, ако искаме да имаме равни обекти, ако имат еднакви имена? Какво да правим? Отговорът: трябва да заменим методите hashCode() и equals() на класа Object за нашия клас Character . Можем да го направим автоматично в IDEA IDE, просто натиснете alt + insert на клавиатурата и изберете Generate -> equals() и hashCode() . Какво е Java hashCode() - 2В случая с нашия пример имаме следния code:

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));
    }
}
Резултатът от изпълнението на този code:

Arnold
1969563338
Arnold
1969563338
true
Така че сега програмата идентифицира нашите обекти като равни и те имат еднакви хеш codeове.

Пример за хаш code на Java:

Ваш собствен hashCode() и equals()

Можете също така да създадете свои собствени реализации на equals() и hashCode() , но бъдете внимателни и не забравяйте да минимизирате сблъсъците с хешcode. Ето пример за нашите собствени методи 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));
   }
}

За 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ове кара програмите да работят по-бързо.
Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION