Hash-principen
Först och främst, innan vi definierar Java-hashkoden, måste vi förstå vad som är hashing och vad det är till för. Hashing är en process för att tillämpa en hashfunktion på vissa data. En hashfunktion är bara en matematisk funktion. Oroa dig inte för detta! "Matematisk" betyder inte alltid "komplicerat". Här betyder det bara att vi har en del data och en viss regel som mappar data till en uppsättning tecken (kod). Det kan till exempel vara ett hexadecimalt chiffer. Vi har en del data av valfri storlek vid ingången och tillämpar en hashfunktion på den. Vid utgången får vi en data med fast storlek, säg 32 tecken. Vanligtvis konverterar den typen av funktion en stor bit data till ett litet heltalsvärde. Resultatet av detta funktionsarbete kallas en hashkod. Hash-funktioner används ofta i kryptografi, och även i vissa andra områden. Hashfunktioner kan vara olika,
- Ett visst objekt har en viss hashkod.
- Om två objekt är lika, är deras hashkoder desamma. Det omvända är inte sant.
- Om hashkoderna är olika, är objekten inte lika med säkerhet.
- Olika objekt kan ha samma hashkod. Det är dock en mycket osannolik händelse. Vid det här laget har vi en kollision, en situation där vi kan förlora data.
Den "riktiga" hashfunktionen minimerar sannolikheten för kollisioner.
Hashcode i Java
I Java är hash-funktionen vanligtvis kopplad till
hashCode()-metoden . Exakt, resultatet av att applicera en hashfunktion på ett objekt är en hashkod. Varje Java-objekt har en hash-kod. I allmänhet är Hash Code ett tal som beräknas med metoden
hashCode() för
Object
klassen. Vanligtvis åsidosätter programmerare denna metod för sina objekt samt relaterad till
hashCode() metoden
equals() för mer effektiv bearbetning av specifik data. Metoden hashCode
() returnerar ett int-värde (4 byte), vilket är en numerisk representation av objektet. Denna hashkod används till exempel av samlingar för effektivare lagring av data och därmed snabbare åtkomst till dem. Som standard är
hashCode()funktion för ett objekt returnerar numret på minnescellen där objektet är lagrat. Därför, om inga ändringar görs i applikationskoden, bör funktionen returnera samma värde. Om koden ändras något ändras även hashkodvärdet. Vad används hashkoden till i Java? Först och främst hjälper Java-hashkoder program att köras snabbare. Om vi till exempel jämför två objekt
o1
och
o2
av någon typ, tar operationen
o1.equals(o2)
cirka 20 gånger längre tid än
o1.hashCode() == o2.hashCode()
.
Java är lika med()
I den överordnade klassen
Object
, tillsammans med metoden
hashCode() finns det också
equals() , funktionen som används för att kontrollera likheten mellan två objekt. Standardimplementeringen av den här funktionen kontrollerar helt enkelt länkarna för två objekt för deras likvärdighet.
equals() och
hashCode() har sitt kontrakt, så om du åsidosätter en av dem bör du åsidosätta den andra, för att inte bryta detta kontrakt.
Implementering av hashCode()-metoden
Exempel
Låt oss skapa en klasskaraktär
med ett fält —
namn . Efter det skapar vi två objekt av
Character class,
character1 och
character2 och ger dem samma namn. Om vi använder standard-
hashCode() och
equals() i klassen
Object kommer vi definitivt att få olika, inte lika objekt. Det är så hashkod i Java fungerar. De kommer att ha olika hashkoder eftersom de finns i olika minnesceller och operationsresultatet
equals() kommer att vara falskt.
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 att köra programmet:
Arnold
1595428806
Arnold
1072408673
false
Två 10-siffriga nummer i konsolen är hashkoder. Vad händer om vi vill ha lika objekt om de har samma namn? Vad ska vi göra? Svaret: vi bör åsidosätta metoderna
hashCode() och
equals() i objektklassen för vår
Character- klass. Vi skulle kunna göra det automatiskt i IDEA IDE, tryck bara på
alt + insert på ditt tangentbord och välj
Generate -> equals() och hashCode() .
![Vad är Java hashCode() - 2]()
När det gäller vårt exempel har vi nästa kod:
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 att köra den här koden:
Arnold
1969563338
Arnold
1969563338
true
Så nu identifierar programmet våra objekt som lika och de har samma hashkoder.
Java-hashcode exempel:
Din egen hashCode() och equals()
Du kan också skapa dina egna realisationer
för equals() och
hashCode() , men var försiktig och kom ihåg att minimera hashkodkollisioner. Här är ett exempel på våra egna
hashCode()- och
equals()- metoder i
Studentklassen :
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));
}
}
Och
huvudklassen för att visa sitt arbete:
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));
}
}
Vad används hashkod till?
Först och främst hjälper hashkoder program att köra snabbare. Om vi till exempel jämför två objekt
o1
och
o2
av någon typ, tar operationen
o1.equals(o2)
ungefär 20 gånger längre tid än o1.hashCode() == o2.hashCode(). I Java står hashprincipen bakom några populära samlingar, såsom
HashMap ,
HashSet och
HashTable .
Slutsats
Varje Java-objekt har
metoderna hashCode() och
equals() som ärvts från klassen
Object . För att få en bra fungerande jämställdhetsmekanism är det bättre att åsidosätta
hashcode()- och
equals()- metoderna för dina egna klasser. Att använda hashkoder gör att program körs snabbare.
GO TO FULL VERSION