String的hashCode和equals问题

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

 

 String的hashCode和equals问题  


能否定义两个字符串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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值