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
o1
og
o2
af 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
Object
sammen 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() - 2]()
I 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;
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();
}
@Override
public int 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>();
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));
Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28));
Student johnny = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28));
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
o1
og
o2
af 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.