Ce face String.hashCode
hashCode() transformă textul într-un număr int, folosit de HashMap și HashSet ca să găsească rapid elementele. Pentru String, formula este fixă și documentată: s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1], cu depășire normală de int. De aceea același text are același cod pe orice calculator și la orice rulare.
Regula importantă: dacă a.equals(b), atunci a.hashCode() == b.hashCode(). Invers nu este adevărat: texte diferite pot avea același cod (o coliziune), de exemplu "Aa" și "BB". Nu folosi niciodată codul hash ca identificator unic sau ca parolă criptată.
Ce returnează
Un int (poate fi și negativ). Șirul gol are codul 0.
Exemple
Exemplul 1: Același text, același cod
public class Main {
public static void main(String[] args) {
String a = "Iași";
String b = new String("Iași");
System.out.println(a.hashCode());
System.out.println(b.hashCode());
System.out.println("".hashCode());
System.out.println("Ana".hashCode());
}
}
Rezultat
2284712
2284712
0
65972
Exemplul 2: Formula, calculată de mână
Reproducem formula cu 31 și comparăm cu rezultatul metodei. Pentru "Aa" și "BB" codurile coincid.
public class Main {
static int hashManual(String s) {
int h = 0;
for (int i = 0; i < s.length(); i++) {
h = 31 * h + s.charAt(i);
}
return h;
}
public static void main(String[] args) {
System.out.println(hashManual("Cluj") + " " + "Cluj".hashCode());
System.out.println("Aa".hashCode() + " " + "BB".hashCode());
System.out.println("Aa".equals("BB"));
}
}
Rezultat
2103518 2103518
2112 2112
false
Greșeli frecvente
- Folosești
hashCode()pentru a verifica dacă două texte sunt egale. Coduri egale nu înseamnă texte egale; foloseșteequals. - Stochezi parole „criptate” cu
hashCode(). Nu este o funcție criptografică; folosește un algoritm dedicat (bcrypt, PBKDF2).
Comenzi înrudite
Object.equals: equals() spune dacă două obiecte sunt „egale”, iar hashCode() dă un număr folosit de HashMap și HashSet; se suprascriu împreună.Objects.hash: hash() calculează un cod hash din mai multe câmpuri (ideal în hashCode()); hashCode(o) dă 0 pentru null.String.equals: Verifică dacă două șiruri au exact același text; equalsIgnoreCase și equalsFoldCase ignoră literele mari/mici.