在java中每一个对象都会有一个hashcode 例如:object,Map,List,String等,如果两个对象,字符串,map所对应的value调用equals()相等 那个比较双方的hashcode一定相等,反之hashcode相等的不一定两个比较值相等,这就是所谓的hash冲突,具体可看map中的实现, String对象的hashcode生成的规则是
我们创建一个JunitCase 类名为 TestHashcodeCase来测试
public class TestHashcodeCase {
@Test
public void testGetOrginHashcode(){
String test = "Test";
System.out.println(" 调用原生的 String生成方法" + test.hashCode());
}
}
输出结果是:2603186
String类中的hashcode源码
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
那源码中的计算规则,我们通过几个示例来说明
@Test
public void testGetHashcodeByCharArray(){
String test = "Test";
System.out.println(" 调用原生的 String生成方法" + testGetHashcodeByCharArray(test));
}
public int testGetHashcodeByCharArray(String str) {
int h = 0;
int len = str.length();
int hash = 0;
if (h == 0 && len > 0) {
int off = 0;
char[] val = str.toCharArray();
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
代码: h = 31*h + val[off++]; 是把val[off++]转换成ASCII来做的计算,如何转换请参考上一篇介绍
我们以一种更明显的方式来说明:
@Test
public void getHashcodeByIntArray(){
String test = "Test";
System.out.println(" 调用原生的 String生成方法" + getHashcodeByIntArray(test));
}
public int getHashcodeByIntArray(String str) {
int h = 0;
int len = str.length();
int hash = 0;
if (h == 0 && len > 0) {
int off = 0;
int val[] = strToAscii(str) ;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
private int[] strToAscii(String str){
char[] chars = str.toCharArray();
int[] ascillCode = new int[chars.length];
for(int i=0;i<chars.length;i++){
System.out.println(""+chars[i]+" = " + (int)chars[i]);
ascillCode[i] = (int)chars[i];
}
return ascillCode;
}
代码: int val[] = strToAscii(str)调用的方式把字节转换为ASCII的数组
转换代码为 : ascillCode[i] = (int)chars[i];
输出的结果都是:2603186
总结:算法规则是:h = 31*h + value; 也就是h每次的每次得到的结果作为下一次的参数代入
四次迭代结果分解如下:
h = 31*h + value;
//第一遍迭代
value = 84;
h = 31*0+84;
h = 84;
//第二遍迭代
value = 101;
h = 31*84+101;
h = 2705;
//第三遍迭代
value = 115;
h = 31*2705+115;
h = 83970;
//第四遍迭代
value = 116;
h = 31*83970+116;
h=2603186;
得到的结果与我们预期的一致
话说每个string变量或者对象都有hashcode,这个hashcode用来做啥作用的呢?是否与map中的hashcode的作用一样呢?我们带着问题去找答案