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
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。
- String的hashCode和equals问题
- String和equals()、hashCode()
- hashCode和equals方法的问题
- hashCode()和equals()的覆写问题
- HashCode和equals的面试问题
- Java中String类hashCode()和equals()问题
- String 中equals方法和hashcode方法
- String类重写equals()和hashCode()方法
- equals和hashCode的区别
- equals和 hashcode的区别
- Equals()和HashCode()的关系
- hashcode和equals的读书笔记
- hashcode和equals的使用
- equals 和 hashcode 的理解
- equals和hashcode的区别
- Java的hashcode()和equals()
- equals()和hashCode()的区别
- equals 和hashcode的区别
- uva 375 Inscribed Circles and Isosceles Triangles 简单几何
- websocket协议
- 可滚动的ResultSet
- 并行分区特性
- 股票基础
- String的hashCode和equals问题
- 浅析调用android的content provider(一)
- 黑马程序员_网络编程1(IP,TCP和UDP,DatagramSocket与DatagramPacket,TCP传输)
- 史玉柱的创业经验谈
- hive数据类型(翻译自Hive Wiki)
- UVA 112 Tree Summing
- 增强视觉 | 计算机视觉 增强现实
- 排序算法整理(2)归并排序
- EOE上的LISTVIEW分组