String.hashcode()的算法规则

在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的作用一样呢?我们带着问题去找答案

 

 

 

 

   

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值