快捷搜索: 王者荣耀 脱发

【面试】String重写equals方法还要重写hashCode方法

一.原因

    1.String类重写了equals方法,在原有Object的equals逻辑的基础上新增了逻辑:如果字符串的value值相同那equals的结果也为true。 2.若不重写hashCode方法,会存在两个字符串对象equals方法结果为true,hashCode方法为false。 3.如果两个对象的hashCode不同,则这两个对象肯定不同。如果两个对象equals相等,hashCode也有可能不同。 4.hashCode方法的好处在于返回值都是数值,比较起来简单,hashCode不同则没有必要去比较equals是否相等,能提高比较的效率。 5.在散列集合中,例如HashMap中,通过大量计算key的hash来计算当前元素的hash在数组所处的位置,用的就是hashCode。只有当hashCode相同时,才会放在同一个数组的位置,再去比较同个位置上的链表或树节点中的元素是否equals,这样先比较一遍hashcode,缩小equals的范围,提高效率。 6.如果String的equals相同,hashCode的不同,这样在HashMap中不同的数组位置可能会存在相同的元素,这是不对的。

二.说明

1.什么是==
1.在Java中,基本数据类型 == 比较的是值;对象类型 == 比较的是对象的地址。
2.String类是使用频率非常高的一种对象类型,JVM为了提升性能和减少开销,避免字符串的重复创建,因此维护了一块特殊的内存空间,即字符串常量池。
3.当需要使用字符串时,先去字符串常量池查看该字符串是否已经存在,如果存在,则可直接使用;如果不存在,则初始化,并将该字符串放入到字符串常量池中。
4.在JDK1.6及之前版本,字符串常量池在方法区中;在JDK1.7及以后版本,字符串常量池在堆中。
5.==判断的是对象内存的地址,因此相同的字符串String str = "abc";String str2 = "abc";在字符串常量池中会返回同样的地址,则返回true。
6.字符串String str = "abc";字符串对象String str2 = new String("abc");字符串对象str2的地址在堆空间,字符串str的地址在字符串常量池,因此两者不相等。
7.字符串对象String str = new String("abc"); 字符串对象String str2 = new String("abc"); str和str2均在堆空间,是2个对象,地址一定是不同的,所以两者不相等。
2.String的equals方法
1.如果内存相同则直接返回true
2.如果是String类型,则先比较value的长度,不同则false,相同则挨个比较字符是否相同,有一个不相同则false

三.源码

1.Object类的equals方法
// Object类的equals方法源码
public boolean equals(Object obj) {
          
   
	return (this == obj);
}
2.String类中的equals方法
public boolean equals(Object anObject) {
          
   
	if (this == anObject) {
          
   
	    return true;
	}
	if (anObject instanceof String) {
          
   
	    String anotherString = (String)anObject;
	    int n = value.length;
	    if (n == anotherString.value.length) {
          
   
	        char v1[] = value;
	        char v2[] = anotherString.value;
	        int i = 0;
	        while (n-- != 0) {
          
   
	            if (v1[i] != v2[i])
	                return false;
	            i++;
	        }
	        return true;
	    }
	}
	return false;
}
3.String类的hashCode方法
public int hashCode() {
          
   
    int h = hash;
    if (h == 0 && value.length > 0) {
          
   
        char val[] = value;

        for (int i = 0; i < value.length; i++) {
          
   
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}
经验分享 程序员 微信小程序 职场和发展