String的hashCode和equals问题

来源:互联网 发布:女款羽绒服淘宝网购物 编辑:程序博客网 时间:2024/06/06 07:22

http://web4.blog.163.com/blog/static/18969413120102291722395/

 

 String的hashCode和equals问题  

问题来源:
http://topic.csdn.net/u/20100326/15/5b112129-9d2e-4449-a57c-4369787a2fc5.html

能否定义两个字符串s1和s2对象,使得以下结论同时成立:
1. s1.eq ls(s2) 得到的结果是false
2. s1.hashCode() == s2.hashCode() 得到的结果是tr 
我的第一反应是不存在这样的String对象。因为String重写了eq ls和hashCode。不经过大脑的得出的答案往往是经不住实践的考验的!
实际上,eq ls=tr可以知道hashCode相等,hashcode不相等那么肯定不eq ls。但是hashcode相等却不eq ls的情况是允许出现的。
为了构造一个这样的情况,我们就需要知道String的hashCode是如何实现的:
 public int hashCode() {  int h = hash;  if (h == 0) {      int off = offset;      char val[] = value;      int len = count;             for (int i = 0; i < len; i++) {                 h = 31*h + val[off++];             }             hash = h;  }   return h;}


其中:
len:字符串的长度
h:初始值为0
val:字符数组,存放的是对应的字符
因此,长度为1的字符串的hashCode也是对应的字符的ascill码,长度为0的字符串的hashCode是0。
因此,要构造两个hashcode相等的字符串转化成为一个解方程问题。
我们直接来看现成的一个结果:
String s1="{~"; 
String s2="|_"; 
System.out.println(s1.eq ls(s2)+","+(s1.hashCode()==s2.hashCode()));//false,tr
"{"ascii是123,"~"的ascii是126,"|"的是124,"_"的是95,123*31+126=124*31+95=3939
很显然,hashCode相等,但是却不eq ls。
而楼主还给出了另外一个更有意思的答案:
String s3="\";
String s4="";
System.out.println(s3.eq ls(s4)+","+(s3.hashCode()==s4.hashCode()));//false,tr
这就有点意思了!
首先,我们要弄明白\是一个什么玩意?\u是一个unicode,而jvm对unicode的处理是在编译时就完成了,那么\代表的是哪个字符呢?
反编译一下看看:
ldc #2; //String  
也就是说String里面是一个空字符串,那么,s4也是空字符串啊,为什么不eq ls呢?
接着做测试:
System.out.println(s3.length());//1
System.out.println(s4.length());//0
现在看出来了,原来一个是长度为1的字符串,只不过它里面的内容是一个unicode字符,这个字符是一个空字符,一个是长度为0的空字符串,连长度都不一样,肯定不eq ls。这是eq ls的源代码:
public boolean eq ls(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;}

 

下面我们来看看hashCode:

System.out.println(s3.hashCode());//0

System.out.println(s4.hashCode());//0

因为他们的内容都是空,根据hashCode的计算方法,hashCode都是0。

原创粉丝点击