Java String 的equals, == , hascode的区别
1、equals 和 ==
==在java中是比较引用的,即在内存中的地址。而String的equals()是比较字符串的内容
http://blog.csdn.net/barryhappy/article/details/6082823
先看这几句代码
- String s1 = "String";
- String s2 = "String";
- System.out.println(s1 == s2 );
- System.out.println(s1.equals(s2));
结果为:
true
true
这个结果说明什么呢?
==在java中是比较引用的,即在内存中的地址。而String的equals()是比较字符串的内容。
第二个true无可争议,因为s1和s2的内容显然 相同。
第一个true呢?
这说明s1和s2的地址相同,s1和s2的地址为什么会相同?
查阅资料,发现 :
String s1 = "String";
这种方式,java首先会在缓冲区查找是否有"String"这个常量对象,有就直接将其地址赋给s1,没有就创建一个"String",然后将其赋给s1;然后
String s2 = "String";
java同样会在缓冲区中查找"String",这次能查找到了,因为s1创建了一个"String",所以会将其地址赋给s2,如此,s1和s2便有了相同的地址。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OK。
再看这一段代码
- String s3 = new String("String");
- String s4 = new String("String");
- System.out.println(s3 == s4);
- System.out.println(s3.equals(s4));
结果为:
false
true
第二个true同样无争议。
第一个false说明s3和s4不是指向同一地址。
查阅资料发现,
String s3 = new String("String");会直接在内存中开辟一个空间存储一个"String",并讲引用赋给s3;
同样 String s4 = new String("String");也会开辟一个空间,降低至给s4;
所以s3和s4的地址不一样。
即
System.out.println(s3 == s4); 会打印出false。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
附
关于String的equals方法:
这是直接从jdk源码复制的equals方法代码:
- public boolean equals(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;
- }
java的String是用字符数组模拟的。
从上面的代码可以看出String的equals()的工作原理——
1、首先比较引用,如果引用相同,返回true;
2、比较类型,如果不是比较的不是String对象,返回false;
3、比较长度,字符串长度不等时,返回false;
4、逐个字符比较两个字符串,遇到不一样的字符,返回false;
5、到最后都一致,返回ture;
2、hashcode
在这里主要是讲==与hashCode()之间的区别。
String str1 = "nihao" ;
String str2 = "nihao" ;
String str3 = new String("nihao");
String str4 = new String("nihao");
System.out.println("str1==str2: " + (str1==str2)); // true
System.out.println("str1==str3: " + (str1==str3)); // false
System.out.println("str3==str4: " + (str3==str4)); // false
System.out.println("HashCode:" + str3.hashCode()); // HashCode:104818427
System.out.println("HashCode:" + str4.hashCode()); // HashCode:104818427
System.out.println(str3.hashCode() == str4.hashCode()); // true
System.out.println(str3.equals(str4)); // true
第一个true,是因为str1和str2是同一个变量,这个变量在变量池中。
第一个false,是因为str1在变量池中,而str3在堆栈中,所以是不同。
第二个false,通过new创建的String,是两个不同的对象。
虽然str3和str4是两个不同的对象,但是其hashCode值是一样的,这就和hashCode()函数有关了,下面是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;
}
}
在String类中,value是该字符串被转换成数组后的对象。由于offset总是为0,所以h一开始就是0。于是只要value是一样的,所 以hashcode一定是一样的。于是可以肯定的说,==在判断对象时,其实是根据对象在堆栈中的地址判断对象是不是一样,而不是根据hashcode 值。
2. http://java.chinaitlab.com/others/773414.html
Java String中的HashCode和equal
1. hashSet中比较是否重复的依据是a.hasCode()=b.hasCode() && a.equals(b)
2. String的hashCode依据: 以依赖于char[i]的int值以和char[i]的排列序的算法计算出的。不依赖String的ref.
3. String的equals依据: a==b || ( a.length=b.length && { a[i]=b[i] } )
4. 只有用a==b时比校的才是比校的ref,也就是说这时才是比校是a与b是不是同一个对象
5. 结论: 两个不同ref的String可能会被认为是集合中的同一个元素。
3.http://hi.baidu.com/songdenggao/blog/item/a7336a607b930d47ebf8f8df.html
关于String.hashCode
String.hashCode(),提供将任意长的字符串哈希成一个整数。
在Java中,整型数是32位的,也就是说最多有2^32= 4294967296个整数,将任意一个字符串,经过hashCode计算之后,得到的整数应该在这4294967296数之中。那么,最多有 4294967297个不同的字符串作hashCode之后,肯定有两个结果是一样的(这个可以用鸽巢定理来解释,hehe)。
下面的两组,其hashCode就相等了:
http://pic.bandaonews.com/PicView.aspx?id=37219
和
http://tech.163.com/05/0829/09/1SAIIRG8000915BD.html
http://news.sina.com.cn/c/2005-06-08/10076113241s.shtml
和
http://news.edw.com.cn/show.aspx?id=3490&cid=25
当用到这样的方法来得到字符串的哈希值,并且此哈希值可能作为系统中的一个比较重要的参数的时候,应该充分考虑到哈希值可能重复的后果并做好一定的容错处理
Java String 的equals, == , hascode的区别的更多相关文章
- java String的equals,intern方法(转载)
JAVA中的equals和==的区别 ==比较的是2个对象的地址,而equals比较的是2个对象的内容. 显然,当equals为true时,==不一定为true: 基础知识的重要性,希望引起大家的重视 ...
- java开发注意点之String使用equals和==的区别
"=="操作符的作用 1.用于基本数据类型的比较 2.判断引用是否指向堆内存的同一块地址. equals所在位置: 在Object类当中,而Object是所有类的父类,包含在jdk ...
- 【java】由equals和==的区别引出的常量池知识
equals和==的区别,百度查到的结果大都是:equals比较的是值,==比较的是引用地址. String str1 = "abc"; String str2 = "a ...
- java中的equals与==的区别
equals是Object类的公共方法,方法内部是用==实现的.但是很多类都重写了equals方法,例如基本数据类型的封装类和String类,重写后比较的是对象的值或者内容是否相同.而==是比较地址, ...
- Java中的equals和==的区别以及几个常用的object中的方法简单的调试方法
一.equals 1.equals:是Object类中的方法,只能判断引用类型 2.默认判断的是地址是否相等(判断两个参数是否是同一个对象),子类中往往重写该方法,用于判断内容(值)是否相等 二.== ...
- java中“==”和equals方法的区别,再加上特殊的String引用类型
==和equals的区别: 1.==是运算符,而equals是基类Object定义的一个方法,并且equals使用==定义的 2.进行比较时,分为 基本数据类型 的比较和 引用数据类型 的比较 ...
- Java中“==”与equals方法的区别
1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...
- Java学习之equals和==的区别
转自:http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html java中的数据类型,可分为两类: 1.基本数据类型 也称原始数 ...
- Java—String,StringBuffer,StringBuilde区别和操作
Java语言有关字符串的类有三种 java.lang.String:一般作为简单字符串类型 java.lang.StringBuffer:字符串缓冲区 java.lang.StringBuider:字 ...
随机推荐
- 《WPF程序设计指南》读书笔记——第2章 基本画刷
1.Color结构 using System; using System.Windows; using System.Windows.Input; using System.Windows.Media ...
- Redhat 显示系统版本号和内核版本号
1./etc/issue 和 /etc/redhat-release都是系统安装时默认的发行版本信息,通常安装好系统后文件内容不会发生变化.[root@rac1 mysql]# cat /etc/is ...
- CSS 将按钮转成超链接样式
一.将按钮转成超链接样式 .GoStyle { color: #0c5fc4; background-color: #FFFFFF; ...
- [译] ASP.NET 生命周期 – ASP.NET 上下文对象(八)
使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...
- easy ui datagrid 设置冻结列
为了冻结列,您需要定义 frozenColumns 属性.frozenColumn 属性和 columns 属性一样. $('#tt').datagrid({ title:'Frozen Column ...
- Cygwin安装与配置
Cygwin可以在windows环境下模拟Linux系统,而且可以重用Linux下面丰富的脚本工具.windows的cmd太弱了.Cygwin是由Cygnus(天鹅座) Solution公司开发,不过 ...
- Sugarcrm Email Integration
Introdurce http://www.sugarcrm.com/feature/email-integration Tutor http://www.youtube.com/watch?v=BQ ...
- jvm 参数调优
FROM: http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction ...
- linux命令useradd添加用户详解
1.作用 useradd或adduser命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户. 2.格式 useradd [-d home] [-s shell] [-c comment] [ ...
- C#查找子串在原串中出现次数
提供的是一种思路,和具体语言无关. string test = "good good study day day up"; string r = test.Replace(&quo ...