java中String.hashCode()方法的算法如下:str.charAt(0) * 31n-1 + str.charAt(1) * 31n-2 + ... + str.charAt(n-1)
据说算法中31这个数字是对英文字符进行优化后产生的一个最佳数字,但是碰上字母大小写或是一些特殊字符,再或者是中文字符,它就不灵了,很容易重复,举个例子:
2017-08-01更新
2018-03-19更新
制作相同hashcode的代码块
System.out.println("\"柳志崇\".hashCode()="+"柳志崇".hashCode());System.out.println("\"柳山왡\".hashCode()="+"柳山왡".hashCode());
int aa= '柳'*31*31+'志'*31+'崇' ;
System.out.println("aa=" + aa);
int ccint = (aa- ('柳'*31*31+ '山'*31) );
System.out.println("ccint=" + ccint);
char cc = (char)ccint;
System.out.println("cc=" + cc);
4个知识点:
1.java中所有的对象都有一个父类Object,而Object类都有hashCode方法,也就是说java中所有的类均会有hashCode方法;
2.Object类的hashCode方法是native的,即是通用C语言来写的,本文举例使用的是String类,自己重写了hashCode方法,算法即如下:
String.hashCode()=str.charAt(0) * 31n-1 + str.charAt(1) * 31n-2 + ... + str.charAt(n-1)
3.String类的hashCode算法是固定的,根据算法就可以看到是可能会存在相同hashCode的
4.再强调一点,两个String的hashCode相同并不代表着equals比较时会相等,他们两者之间是没有必然关系,这一点可以看看equals方法的实现
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}