字符串比较 equals

字符串比较如果用“==”会出现下面的情况

<span style="font-size:14px;">//字符串的比较
String abc = "abc";
String abc2 = "abc";
String abc3 = newString("abc");
System.out.println("abc == abc2:"+ (abc == abc2));   //这里比较的是abc、abc2的地址,在同一个sring池内,地址相同。
System.out.println("abc == abc3:"+ (abc == abc3));  </span>
<span style="font-size:14px;">//输出结果</span>
<span style="font-size:14px;">abc == abc2:true</span>
<span style="font-size:14px;">abc == abc3:false
</span>

这里涉及到string池的概念

当使用equals比较字符串时,实际比较的是字符串的hashCode,而且这里需要理解另外一个知识点——不同数据类型的哈希码算法


哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。
 
下面给出几个常用的哈希码的算法。
1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串内容相同,返回的哈希码也相同。
3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,两个一样大小的Integer对象,返回的哈希码也一样。

因为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;  
   }  
所以相同字符串的String对象的hashCode值一定相等,但是字符串内容不相同的hashCode值可能会相等,因为String的hashCode的值域范围是有限的,而字符串的长度和排列组合方式是无穷多种的。

String类重写的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;  
    }  

它首先判断的是两个对象的引用是否指向同一内存地址,是的话就返回true ,否则继续往下走,
往下走时,判断是否为String类的对象,然后比较两个字符串的长度和内存,当都相等的时候就返回true ,否则返回false。
 
而在Object类中的equals()方法为:
public boolean equals(Object obj) {  
return (this == obj);  
   }  
很明显,它比较的就是两个对象的引用所指向的内存地址

验证一下
public static void main(String arg[]) {
		String str1 = "abc";
		String str2 = "abc";
		String str3 = new String("abc");
		String str4 = new String("abc");
		System.out.println(str1.hashCode()); // 96354
		System.out.println(str2.hashCode()); // 96354
		System.out.println(str3.hashCode()); // 96354
		System.out.println(str4.hashCode()); // 96354

		System.out.println(str1 == str2);		//true
		System.out.println(str1.equals(str2));	<span style="white-space:pre">	</span>//true
		System.out.println(str3 == str4);		//false
		System.out.println(str3.equals(str4));	<span style="white-space:pre">	</span>//true
		System.out.println(str1 == str3);		//false
		System.out.println(str1.equals(str3));	<span style="white-space:pre">	</span>//true
	}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值