CodeGym /Java blog /Tilfældig /Java hashCode()
John Squirrels
Niveau
San Francisco

Java hashCode()

Udgivet i gruppen

Hash-princippet

Først og fremmest, før vi definerer Java-hashkoden, skal vi forstå, hvad der er hashing, og hvad det er til. Hashing er en proces med at anvende en hash-funktion på nogle data. En hash-funktion er blot en matematisk funktion. Du skal ikke bekymre dig om dette! "Matematisk" betyder ikke altid "kompliceret". Her betyder det kun, at vi har nogle data og en bestemt regel, der kortlægger dataene i et sæt tegn (kode). Det kunne for eksempel være en hexadecimal chiffer. Vi har nogle data af enhver størrelse ved indgangen og anvender en hash-funktion til det. Ved udgangen får vi en fast størrelse data, f.eks. 32 tegn. Normalt konverterer den slags funktion et stort stykke data til en lille heltalsværdi. Resultatet af dette funktionsarbejde kaldes en hash-kode. Hash-funktioner er meget udbredt i kryptografi, og også nogle andre områder. Hash-funktioner kan være forskellige,
  • Et bestemt objekt har en bestemt hashkode.
  • Hvis to objekter er ens, er deres hashkoder de samme. Det omvendte er ikke sandt.
  • Hvis hash-koderne er forskellige, så er objekterne ikke ens med sikkerhed.
  • Forskellige objekter kan have den samme hash-kode. Det er dog en meget usandsynlig begivenhed. På dette tidspunkt har vi en kollision, en situation, hvor vi kan miste data.
Den "korrekte" hash-funktion minimerer sandsynligheden for kollisioner.

Hashcode i Java

I Java er hash-funktionen normalt forbundet med hashCode()-metoden . Præcis, resultatet af at anvende en hash-funktion på et objekt er en hashkode. Hvert Java-objekt har en hash-kode. Generelt er Hash Code et tal, der beregnes af klassens hashCode() metode Object. Normalt tilsidesætter programmører denne metode for deres objekter samt relateret til hashCode() equals ()- metoden for mere effektiv behandling af specifikke data. Metoden hashCode() returnerer en int (4 bytes) værdi, som er en numerisk repræsentation af objektet. Denne hashkode bruges for eksempel af samlinger til mere effektiv lagring af data og dermed hurtigere adgang til dem. Som standard er hashCode()funktion for et objekt returnerer nummeret på den hukommelsescelle, hvor objektet er gemt. Derfor, hvis der ikke foretages ændringer i applikationskoden, skal funktionen returnere den samme værdi. Hvis koden ændres lidt, ændres hashkodeværdien også. Hvad bruges hashkoden til i Java? Først og fremmest hjælper Java-hashkoder programmer med at køre hurtigere. For eksempel, hvis vi sammenligner to objekter o1og o2af en eller anden type, tager operationen o1.equals(o2)omkring 20 gange længere tid end o1.hashCode() == o2.hashCode().

Java er lig med()

I den overordnede klasse er der Objectsammen med metoden hashCode() også equals() , den funktion, der bruges til at kontrollere ligheden af ​​to objekter. Standardimplementeringen af ​​denne funktion kontrollerer simpelthen linkene til to objekter for deres ækvivalens. equals() og hashCode() har deres kontrakt, så hvis du tilsidesætter en af ​​dem, bør du tilsidesætte den anden, for ikke at bryde denne kontrakt.

Implementering af hashCode() metoden

Eksempel

Lad os oprette et klassekarakter med ét felt — navn . Derefter opretter vi to objekter af Character class, character1 og character2 og giver dem samme navn. Hvis vi bruger standard hashCode() og equals() i Object- klassen, vil vi helt sikkert få forskellige, ikke lige objekter. Det er sådan hashkode i Java fungerer. De vil have forskellige hashkoder, fordi de er i forskellige hukommelsesceller, og operationsresultatet equals() vil være falsk.

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));
    }
}
Resultatet af at køre programmet:

Arnold
1595428806
Arnold
1072408673
false
To 10-cifrede tal i konsollen er hashkoder. Hvad hvis vi ønsker at have ens objekter, hvis de har de samme navne? Hvad skal vi gøre? Svaret: vi bør tilsidesætte hashCode() og equals() metoderne i Object klasse for vores Character klasse. Vi kunne gøre det automatisk i IDEA IDE, bare tryk på alt + insert på dit tastatur og vælg Generer -> lig med() og hashCode() . Hvad er Java hashCode() - 2I tilfælde af vores eksempel har vi den næste kode:

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));
    }
}
Resultatet af at køre denne kode:

Arnold
1969563338
Arnold
1969563338
true
Så nu identificerer programmet vores objekter som lige, og de har de samme hashkoder.

Java hashkode eksempel:

Din egen hashCode() og er lig med()

Du kan også oprette dine egne equals() og hashCode() realisationer, men vær forsigtig og husk at minimere hashcode-kollisioner. Her er et eksempel på vores egen hashCode() og equals() metoder i Student- klassen:

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));
   }
}
Og hovedklassen for at demonstrere deres arbejde:

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

Hvad bruges hashcode til?

Først og fremmest hjælper hashkoder programmer med at køre hurtigere. For eksempel, hvis vi sammenligner to objekter o1og o2af en eller anden type, tager operationen o1.equals(o2)omkring 20 gange længere tid end o1.hashCode() == o2.hashCode(). I Java står hashing-princippet bag nogle populære samlinger, såsom HashMap , HashSet og HashTable .

Konklusion

Hvert Java-objekt har metoderne hashCode() og equals() nedarvet fra Object- klassen. For at få en god fungerende lighedsmekanisme, må du hellere tilsidesætte hashcode() og equals() metoder for dine egne klasser. Brug af hashkoder får programmerne til at køre hurtigere.
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION