CodeGym /Java blog /Véletlen /Java hashCode()
John Squirrels
Szint
San Francisco

Java hashCode()

Megjelent a csoportban

Hash-elv

Először is, mielőtt meghatároznánk a Java hashkódot, meg kell értenünk, hogy mi a hash, és mire való. A kivonatolás olyan folyamat, amelynek során egyes adatokra hash függvényt alkalmaznak. A hash függvény csak egy matematikai függvény. Ne törődj ezzel! A „matematikai” nem mindig azt jelenti, hogy „bonyolult”. Itt ez csak azt jelenti, hogy van néhány adatunk és egy bizonyos szabályunk, amely leképezi az adatokat egy karakterkészletre (kódra). Ez lehet például egy hexadecimális titkosítás. Bármilyen méretű adatunk van a bemeneten, és alkalmazunk rá egy hash függvényt. A kimeneten egy fix méretű adatot kapunk, mondjuk 32 karaktert. Általában ez a fajta függvény egy nagy adatot kis egész számmá alakít át. Ennek a függvénymunkának az eredményét hash kódnak nevezzük. A hash függvényeket széles körben használják a kriptográfiában és néhány más területen is. A hash függvények különbözőek lehetnek,
  • Egy adott objektumnak van egy adott hashkódja.
  • Ha két objektum egyenlő, akkor a hashkódjuk megegyezik. Ennek a fordítottja nem igaz.
  • Ha a hash kódok különböznek, akkor az objektumok biztosan nem azonosak.
  • A különböző objektumok ugyanazzal a hash kóddal rendelkezhetnek. Ez azonban nagyon valószínűtlen esemény. Ezen a ponton van egy ütközés, egy olyan helyzet, amikor adatokat veszíthetünk.
A „megfelelő” hash függvény minimalizálja az ütközések valószínűségét.

Hashcode Java nyelven

Java-ban a hash függvény általában a hashCode() metódushoz kapcsolódik . Pontosabban, ha egy hash függvényt alkalmazunk egy objektumra, akkor ez egy hashkód. Minden Java objektumnak van hash kódja. Általában a Hash Code egy szám, amelyet az osztály hashCode() metódusa számít ki Object. Általában a programozók felülírják ezt a metódust az objektumaiknál, valamint a hashCode() -hoz kapcsolják az equals() metódust az adott adatok hatékonyabb feldolgozása érdekében. A hashCode() metódus egy int (4 bájt) értéket ad vissza, amely az objektum numerikus ábrázolása. Ezt a hashkódot például a gyűjtemények használják az adatok hatékonyabb tárolására, és ennek megfelelően a gyorsabb hozzáférésre. Alapértelmezés szerint a hashCode()Az objektum függvénye annak a memóriacellának a számát adja vissza, ahol az objektum tárolva van. Ezért, ha nem történik változás az alkalmazás kódjában, akkor a függvénynek ugyanazt az értéket kell visszaadnia. Ha a kód kissé megváltozik, a hashcode értéke is megváltozik. Mire használható a hashkód a Java-ban? Mindenekelőtt a Java hashkódok segítenek a programok gyorsabb futtatásában. Például, ha összehasonlítunk két objektumot o1és o2valamilyen típusú, a művelet o1.equals(o2)körülbelül 20-szor több időt vesz igénybe, mint o1.hashCode() == o2.hashCode().

Java egyenlő ()

A szülőosztályban a hashCode()Object metódus mellett megtalálható az equals() függvény is, amely két objektum egyenlőségének ellenőrzésére szolgál. Ennek a függvénynek az alapértelmezett megvalósítása egyszerűen ellenőrzi két objektum hivatkozásait az egyenértékűség szempontjából. az equals() és a hashCode()-nak megvan a szerződése, tehát ha felülírja az egyiket, felül kell írnia a másikat is, hogy ne szegje meg ezt a szerződést.

A hashCode() metódus megvalósítása

Példa

Hozzunk létre egy osztályt Karakter egy mezővel — név . Ezután létrehozunk két karakterosztályú objektumot , a karakter1 és a karakter2 , és ugyanazt a nevet adjuk nekik. Ha az Object osztály alapértelmezett hashCode()- ját és equals()-jét használjuk , akkor biztosan különböző, nem egyenlő objektumokat kapunk. Így működik a hashcode a Java-ban. Különböző hashkódjaik lesznek, mert különböző memóriacellákban vannak, és az equals() művelet eredménye hamis lesz.

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));
    }
}
A program futtatásának eredménye:

Arnold
1595428806
Arnold
1072408673
false
A konzolban található két 10 jegyű szám hashkód. Mi van akkor, ha egyenlő objektumokat akarunk, ha azonos nevük van? Mit tehetünk? A válasz: felül kell bírálnunk az Object osztály hashCode() és equals() metódusait a Character osztályunkban . Az IDEA IDE-ben automatikusan megtehetjük, csak nyomja meg az Alt + Enter billentyűt a billentyűzeten, és válassza a Generate -> equals() és a hashCode() lehetőséget . Példánk esetében a következő kódot kapjuk: Mi az a 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));
    }
}
A kód futtatásának eredménye:

Arnold
1969563338
Arnold
1969563338
true
Tehát most a program egyenlőnek azonosítja az objektumainkat, és azonos hashkódokkal rendelkeznek.

Java hashcode példa:

Saját hashCode() and equals()

Létrehozhat saját equals() és hashCode() megvalósításokat is, de legyen óvatos, és ne felejtse el minimalizálni a hashcode ütközéseket. Íme egy példa a saját hashCode() és equals() metódusainkra a Student osztályban:

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));
   }
}
A főosztály pedig bemutatja munkájukat:

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));
   }
}

Mire használható a hashcode?

Mindenekelőtt a hashkódok segítenek a programok gyorsabb futtatásában. Például, ha összehasonlítunk két objektumot o1és o2valamilyen típusú, a művelet o1.equals(o2)körülbelül 20-szor több időt vesz igénybe, mint az o1.hashCode() == o2.hashCode(). A Java hashelési elve néhány népszerű gyűjtemény mögött áll, mint például a HashMap , HashSet és HashTable .

Következtetés

Minden Java objektum rendelkezik az Object osztályból örökölt hashCode() és equals() metódusokkal . Egy jól működő egyenlőségi mechanizmus eléréséhez jobb, ha felülírja a hashcode() és equals() metódusokat a saját osztályaiban. A hashkódok használatával gyorsabban futnak a programok.
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION