A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何超 中级黑马   /  2013-11-28 17:38  /  1839 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何超 于 2013-11-29 12:25 编辑

  1. public class Demo {

  2. public static void main(String[] args)
  3. {
  4.         String a="a";
  5.         String b=a;
  6.         String c=b+a;
  7.         String d="a"+"a";
  8.         String m=new String("a");
  9.         
  10.         System.out.println(c.hashCode()+"--"+d.hashCode()+"--"+m.hashCode());
  11.         System.out.println(c.equals(d));
  12.         System.out.println(c==d);
  13. }
  14. }
复制代码
这里的哈希值返回的是什么?
控制台结果是
3104--3104--97
true
false

评分

参与人数 1技术分 +1 收起 理由
简★零度 + 1 神马都是浮云

查看全部评分

9 个回复

倒序浏览
忘了说  如果 是 String m=new String("a")
输出结果 m的哈希值也是3104
回复 使用道具 举报
"a"的哈希值是97,"a"+"a"的哈希值是3104。
回复 使用道具 举报
首先,说下哈希值。
哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。
String类中的hashCode()方法返回此字符串的哈希码。String 对象的哈希码根据以下公式计算:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希值为 0。)
  1. public class Test6 {

  2. public static void main(String[] args)
  3. {
  4.         String a="a";
  5.         String b=a;        //a没有加“”,表示把String b指向了a,
  6.         String c=b+a;//这里b+a其实就是“aa”。
  7.         String d="a"+"a";
  8.         String m=new String("a");
  9.         
  10.         
  11.         System.out.println(c.hashCode()+"--"+d.hashCode()+"--"+m.hashCode());
  12.         //因为c=“aa”;d=“aa”,所以c.hashCode()和d.hashCode()表示的其实就是"aa".hashCode()。
  13.         System.out.println(c);
  14.         System.out.println(c.equals(d));//String类中的equals()方法比较的是两个字符串是否相等,所以返回true
  15.         System.out.println(c==d);//==比较的是两个对象的地址值是否相等,所以返回是false。
  16.         }
  17. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
简★零度 + 1

查看全部评分

回复 使用道具 举报
还有忘了说,String m=new String("a")
m的哈希值不是3104,而是97。楼主可以写个方法试试。
回复 使用道具 举报
殷挥笔 发表于 2013-11-28 19:44
首先,说下哈希值。
哈希算法将任意长度的二进制值映射为固定长度的较小二进制值,这个小的二进制值称为哈 ...

哈希值不就是简易地址描述么   c和d的哈希值都一样了 地址比较为什么不一样?
回复 使用道具 举报
何超 中级黑马 2013-11-28 20:36:48
7#
殷挥笔 发表于 2013-11-28 19:45
还有忘了说,String m=new String("a")
m的哈希值不是3104,而是97。楼主可以写个方法试试。 ...

哈希值一样 equals也是true  就是 ==不一样 为什么······
回复 使用道具 举报
  1. package string;

  2. public class StringHashCodeTest {

  3.         //s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
  4.         /*
  5.          * public int hashCode()
  6.          * 返回此字符串的哈希码。String 对象的哈希码根据以下公式计算:
  7.                 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
  8.                 使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希值为 0。)
  9.                
  10.                 覆盖:
  11.                 类 Object 中的 hashCode
  12.                 返回:
  13.                 此对象的哈希码值。
  14.                 另请参见:
  15.                 Object.equals(java.lang.Object), Hashtable

  16.          *
  17.          *
  18.                 public boolean equals(Object anObject)
  19.                 将此字符串与指定的对象比较。
  20.                 当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,
  21.                 结果才为 true。
  22.                
  23.                 覆盖:
  24.                 类 Object 中的 equals
  25.                 参数:
  26.                 anObject - 与此 String 进行比较的对象。
  27.                 返回:
  28.                 如果给定对象表示的 String 与此 String 相等,则返回 true;否则返回 false。
  29.                 另请参见:
  30.                 compareTo(String), equalsIgnoreCase(String)

  31.          *
  32.          *
  33.          * */

  34.         public static void main(String[] args)
  35.         {
  36.                 //97*1=97
  37.                 String a="a";
  38.                 //97*1=97
  39.                 String b=a;
  40.                 //97*31+97=3104
  41.                 String c=b+a;
  42.                 //97*31+97=3104
  43.                 String d="a"+"a";
  44.                 //97*1=97
  45.                 String m=new String("a");
  46.                
  47.                 
  48.                 //上面的注释根据API给出的算法计算每个字符串的hashCode,所以这里不需要解释了
  49.                 System.out.println(c.hashCode()+"--"+d.hashCode()+"--"+m.hashCode());
  50.                 /*
  51.                  * String重写了Object中的equals方法
  52.                  * 就是判断字符串内容是否相同
  53.                  * 所以这里不难理解
  54.                  * */
  55.                 System.out.println(c.equals(d));
  56.                
  57.                 //这里涉及到一个常量池的概念,不在代码里说了,下面会说
  58.                 System.out.println(c==d);       
  59.         }
  60. }
复制代码


http://developer.51cto.com/art/201106/266454.htm这里是一个研究JVM的人的说法
简单的说,就是所有以"ddd"这种形式赋值的String变量都是通过中间常量,最后在常量池中组合出一个常量,地址赋值给这个变量的,而任何通过对象或者new方法产生的对象都在编译时期无法确定的,所以都是在运行时期在堆中重新开辟的空间,然后赋值的,这里d是通过常量计算得来的,而c不是,所以c和d的地址值不同,所以不等

评分

参与人数 1技术分 +1 收起 理由
简★零度 + 1 很给力!

查看全部评分

回复 使用道具 举报
何超 发表于 2013-11-28 20:35
哈希值不就是简易地址描述么   c和d的哈希值都一样了 地址比较为什么不一样? ...

因为String类中的equals()方法比较的是字符串,==比较的是两个对象的地址,所以==的时候是false
回复 使用道具 举报
何超 中级黑马 2013-11-29 12:24:53
10#
冯晓骏 发表于 2013-11-28 21:13
http://developer.51cto.com/art/201106/266454.htm这里是一个研究JVM的人的说法
简单的说,就是所有以"d ...

太感谢了  这个解释的很清楚
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马