关于String类中重写Object类中的方法

Object作为所有类的基类,它里面定义了许多的方法,最为常见的就是hashCode()、equals()、toString()方法。

一、hashCode()方法

首先来看一下什么是哈希码(HashCode)

在Java中,哈希码代表对象的特征。
例如对象 String str1 = “aa”, str1.hashCode= 3104
String str2 = “bb”, str2.hashCode= 3106
String str3 = “aa”, str3.hashCode= 3104
根据HashCode由此可得出str1!=str2,str1==str3
哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。
下面给出几个常用的哈希码的算法。
1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串内容相同,返回的哈希码也相同。
3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
我们可以通过一个实例看验证一下以上算法:
Object obj1 = new Object();
Object obj2 = new Object();
System.out.println(obj1.hashCode()); //31843011
System.out.println(obj2.hashCode()); //25860399
结果验证了算法的实现,每个Object对象的内存地址都不一样,所以哈希码也不一样。
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str3.hashCode()); //96354
System.out.println(str4.hashCode()); //96354
结果验证了算法的实现,在String类中只要字符串的内容相同,那么返回的哈希码也相同。
因为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的值域范围是有限的,而字符串的长度和排列组合方式是无穷多种的。
在重写hashCode要遵守 hashCode常规协定
一致性
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。

equals

如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果,注:这里说的equals(Object) 方法是指Object类中未被子类重写过的equals方法。

附加

如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高 哈希表的性能。

二、equals()方法

关于String类重写了equals()方法,我们先来看一段代码运行结果:
    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1.hashCode()); // 96354
    System.out.println(str2.hashCode()); // 96354
    System.out.println(str1 == str2); // true
    System.out.println(str1.equals(str2)); // true

    String str3 = new String("abc");
    String str4 = new String("abc");
    System.out.println(str3.hashCode()); // 96354
    System.out.println(str4.hashCode()); // 96354
    System.out.println(str1 == str3); // false
    System.out.println(str1.equals(str3)); // true

关于String str = "abc" 与 String str = new String("abc") 它们在JVM虚拟机中运行情况是不同的,具体的可以参考我的前一篇文章: http://blog.csdn.net/wulianghuan/article/details/8602254
我们可以看到,在String的对象中,对象的内容相同的时候,并不代表它们在内存中的地址也相同,所以equals返回true 而'=='返回false。
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);
    }

很明显,它比较的就是两个对象的引用所指向的内存地址。

三、toString()方法

先通过代码来看一下Object类和String类的toString的方法:

 Object obj1 = new Object();
 System.out.println(obj1.toString());		//java.lang.Object@1e5e2c3
 String str1 = "abc";
 System.out.println(str1.toString());		//abc

我们可以看到String对象的toString()方法仅仅是输出了它的内容。

Object类中的toString()源代码:

    public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

String类中的toString()源代码:

    public String toString() {
	return this;
    }




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值