文章目录
在Java中String数据类型,是如何转化为十进制的值的
话不多说直接上代码
public static void main(String[] args) {
String str1 = "通话";
String str2 = "重地";
String str3 = "你好";
System.out.println("str1的hashcode是:"+str1.hashCode());
System.out.println("str2的hashcode是:"+str2.hashCode());
System.out.println("str3的hashcode是:"+str3.hashCode());
System.out.println("a的hashcode是:"+"a".hashCode());
System.out.println("A的hashcode是:"+"A".hashCode());
System.out.println("Aa的hashcode是:"+"Aa".hashCode());
System.out.println("哀悼的hashcode是:"+"哀悼".hashCode());
}
输出结果
str1的hashcode是:1179395
str2的hashcode是:1179395
str3的hashcode是:652829
a的hashcode是:97
A的hashcode是:65
Aa的hashcode是:2112
哀悼的hashcode是:697340
这里的hashcode()的值是如何计算出来的呢?
我们先分析一下
a的hash值是97,A的hash值是65 。。。。。。这不就是ASCII编码对照的值么
那么问题来了,Aa的hashcode()值不应该是65+97=162么!为什么是2112呢?
还有,中文字符串的hashcode()是如何计算出来的?"通话"和"重地"的HashCode值为什么一样?
分析String的hashcode() 源码
String类的1465行
private final char value[];
private int hash;
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
解析源码
Aa的hashcode()值不应该是65+97=162么!为什么是2112呢?
1.String a = “Aa”;实际就等于String a = new String("Aa);
2. 根据ASCII编码对照A=65,a=97
3.带入源码可知"Aa"被拆分成了数组char vaule[‘A’,‘a’];
4. 带入到hashcode源码逻辑可知:hash没有被赋值,所以这里hash变量的值为int的默认值:0
5."Aa"带入HashCode计算公式:31 * 65 + 97 = 2112
中文字符串的hashcode()是如何计算出来的?
1.String str1 = “通话”;实际就等于String str1 = new String("通话);
2.带入源码可知str1被拆分成了数组char vaule[‘通’,‘话’];
3.在Java中呢char是存储unicode编码的,unicode编码中有中文汉字,我们可以查询一下‘通’,‘话’分别在unicode中转化为10进制的值
4.‘通’,对应unicode编码的10进制值为:36890;‘话’对应unicode编码的10进制值为:35805;
5."通话"带入HashCode计算公式:31 * 36890 + 35805 = 1179395
public static void main(String[] args) {
//unicode 编码总长度为:2^16
for (int i = 0; i < 65536; i++){
char str = (char) i;
if (str == '通' | str == '话'){
System.out.println(i+":"+str);
}
if (str == '重' | str == '地'){
System.out.println(i+":"+str);
}
}
}
输出结果
22320:地
35805:话
36890:通
37325:重
为什么‘’通话’‘和‘’重地‘’hashcode一样?
根据上面的代码,可以计算出“通话”和“重地”分别对应的unicode编码为:
- 通:36890
- 话:35805
- 重:37325
- 地:22320
分别带入String对象的HashCode计算公式
- 通话:
31 * 36890 + 35805 = 1179395 - 重地:
31 * 37325 + 22320 = 1179395
结论
String字符串中的汉字,会被初始化为char数组
,数组中存储的各个中文字符对应的unicode编码值;整个hashcode的运算是将数组中的元素(unicode编码值)逐个带入公式(h = 31 * h + val[i])运算得来。
分享一句我特别喜欢的话:每一天都是一个新的日子,走运当然是好的,不过我情愿做到分毫不差。这样,运气来的时候,你就有准备了。 ————海明威《老人与海》