深入了解String,特别是==与hashCode()

时间:2021-03-05 16:48:16

http://blog.csdn.net/woxueliuyun/article/details/3903102


关于==,equal(),在其它很多网站和博客中已经有说明,在这里主要是讲==与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值。