CodeGym /Java-blogg /Tilfeldig /Java hashCode()
John Squirrels
Nivå
San Francisco

Java hashCode()

Publisert i gruppen

Hash-prinsippet

Først av alt, før vi definerer Java-hashcode, må vi forstå hva som er hashing og hva det er for. Hashing er en prosess for å bruke en hash-funksjon på enkelte data. En hash-funksjon er bare en matematisk funksjon. Ikke bekymre deg for dette! "Matematisk" betyr ikke alltid "komplisert". Her betyr det bare at vi har noen data og en bestemt regel som kartlegger dataene til et sett med tegn (kode). Det kan for eksempel være et heksadesimalt chiffer. Vi har noen data av enhver størrelse ved inngangen, og bruker en hash-funksjon på den. Ved utgangen får vi en fast størrelse på data, for eksempel 32 tegn. Vanligvis konverterer den typen funksjon et stort stykke data til en liten heltallsverdi. Resultatet av dette funksjonsarbeidet kalles en hash-kode. Hash-funksjoner er mye brukt i kryptografi, og noen andre områder også. Hash-funksjoner kan være forskjellige,
  • Et bestemt objekt har en bestemt hashkode.
  • Hvis to objekter er like, er hashkodene deres like. Det motsatte er ikke sant.
  • Hvis hash-kodene er forskjellige, er ikke objektene like sikkert.
  • Ulike objekter kan ha samme hash-kode. Det er imidlertid en svært usannsynlig hendelse. På dette tidspunktet har vi en kollisjon, en situasjon hvor vi kan miste data.
Den "riktige" hash-funksjonen minimerer sannsynligheten for kollisjoner.

Hashcode i Java

I Java er hash-funksjonen vanligvis koblet til hashCode()-metoden . Nettopp resultatet av å bruke en hash-funksjon på et objekt er en hashkode. Hvert Java-objekt har en hash-kode. Generelt er Hash Code et tall som beregnes av hashCode() -metoden til Objectklassen. Vanligvis overstyrer programmerere denne metoden for objektene sine, samt relatert til hashCode() equals ()- metoden for mer effektiv behandling av spesifikke data. HashCode () -metoden returnerer en int-verdi (4 byte), som er en numerisk representasjon av objektet. Denne hashkoden brukes for eksempel av samlinger for mer effektiv lagring av data og følgelig raskere tilgang til dem. Som standard er hashCode()funksjon for et objekt returnerer nummeret til minnecellen der objektet er lagret. Derfor, hvis det ikke gjøres endringer i applikasjonskoden, bør funksjonen returnere samme verdi. Hvis koden endres litt, endres også hashkodeverdien. Hva brukes hashkoden til i Java? Først av alt hjelper Java-hashkoder programmer til å kjøre raskere. For eksempel, hvis vi sammenligner to objekter o1og o2av en eller annen type, tar operasjonen o1.equals(o2)omtrent 20 ganger mer tid enn o1.hashCode() == o2.hashCode().

Java er lik()

I den overordnede klassen Object, sammen med hashCode()- metoden, er det også equals() , funksjonen som brukes til å sjekke likheten til to objekter. Standardimplementeringen av denne funksjonen sjekker ganske enkelt koblingene til to objekter for deres ekvivalens. equals() og hashCode() har sin kontrakt, så hvis du overstyrer en av dem, bør du overstyre den andre, for ikke å bryte denne kontrakten.

Implementering av hashCode()-metoden

Eksempel

La oss lage et klassekarakter med ett felt – navn . Etter det lager vi to objekter av Character class, character1 og character2 og setter dem samme navn. Hvis vi bruker standard hashCode() og equals() i Object- klassen, vil vi definitivt få forskjellige, ikke like objekter. Det er slik hashkode i Java fungerer. De vil ha forskjellige hashkoder fordi de er i forskjellige minneceller, og resultatet av operasjonen equals() vil være usann.

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 av å kjøre programmet:

Arnold
1595428806
Arnold
1072408673
false
To 10-sifrede tall i konsollen er hashkoder. Hva om vi ønsker å ha like objekter hvis de har samme navn? Hva skal vi gjøre? Svaret: vi bør overstyre hashCode() og equals()- metodene i Object- klassen for vår Character- klasse. Vi kunne gjøre det automatisk i IDEA IDE, bare trykk alt + insert på tastaturet og velg Generer -> lik() og hashCode() . Hva er Java hashCode() - 2I tilfellet med vårt eksempel har vi den neste koden:

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 av å kjøre denne koden:

Arnold
1969563338
Arnold
1969563338
true
Så nå identifiserer programmet objektene våre som like, og de har de samme hashkodene.

Java hashkode eksempel:

Din egen hashCode() og lik()

Du kan også lage dine egne equals()- og hashCode()- realiseringer, men vær forsiktig og husk å minimere hashkodekollisjonene. Her er et eksempel på våre egne 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 å demonstrere arbeidet sitt:

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

Hva brukes hashkode til?

Først av alt hjelper hashkoder programmer til å kjøre raskere. For eksempel, hvis vi sammenligner to objekter o1og o2av en eller annen type, tar operasjonen o1.equals(o2)omtrent 20 ganger mer tid enn o1.hashCode() == o2.hashCode(). I Java står hashing-prinsippet bak noen populære samlinger, for eksempel HashMap , HashSet og HashTable .

Konklusjon

Hvert Java-objekt har metodene hashCode() og equals() som er arvet fra Object- klassen. For å få en god fungerende likhetsmekanisme, bør du overstyre hashcode() og equals()- metodene for dine egne klasser. Bruk av hashkoder gjør at programmer kjører raskere.
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION