哈希算法 String.hashCode
public static void main(String[] args) {
String str1 = "abc";
String str2 = "bca";
int hash = 0;
for (int i = 0; i < str2.length(); i++) {
char c = str1.charAt(i);
System.out.println((int)c);
hash += c;
}
System.out.println(hash);
}
以上hash值是将每个字符的值相加得到一个hashcode,但问题是"abc" 与 "cba" 的hashcode 就会一致。如何解决?
可以给前两位字符都乘以一个权重,如下
a * 100 + b * 10 + c
b * 100 + c * 10 + a
实现如下:
public static void main(String[] args) {
String str1 = "abc";
String str2 = "bca";
System.out.println("str1 => String.hashCode:" + str1.hashCode());
System.out.println("str2 => String.hashCode:" + str2.hashCode());
int hash = 0;
for (int i = 0; i < str1.length(); i++) {
char c = str1.charAt(i);
System.out.println((int) c);
hash = hash * 10 + c; //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
}
System.out.println(hash);
}
还可以进一步优化, 将 hash * 10 改为 乘以一个质数 如31 ,但是为什么是指数那?
public static void main(String[] args) {
String str1 = "abc";
String str2 = "bca";
System.out.println("str1 => String.hashCode:" + str1.hashCode());
System.out.println("str2 => String.hashCode:" + str2.hashCode());
int hash = 0;
for (int i = 0; i < str1.length(); i++) {
char c = str1.charAt(i);
System.out.println((int) c);
hash = hash * 31 + c; //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
}
System.out.println(hash);
}
输出:
str1 => String.hashCode:96354
str2 => String.hashCode:97344
97
98
99
96354
此时输出的hashcode 就是 String 类的实现,还可以进一步优化: 将乘法运算转换为 左移位运算,因为位运算的效率比乘法高,32为 2 的 5次方,因此可以左移5位
public static void main(String[] args) {
String str1 = "abc";
String str2 = "bca";
System.out.println("str1 => String.hashCode:" + str1.hashCode());
System.out.println("str2 => String.hashCode:" + str2.hashCode());
int hash = 0;
for (int i = 0; i < str1.length(); i++) {
char c = str1.charAt(i);
System.out.println((int) c);
hash = (hash << 5) - hash + c; //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
}
System.out.println(hash);
}
标签:hash,String,实现,str1,System,hashCode,哈希,JAVA,out
From: https://www.cnblogs.com/czzz/p/18328212