"=="运算符
1.基本数据类型
基本数据类型进行值的比较
public class Test09 {
public static void main(String[] args) {
int number1 = 5;
int number2 = 3;
int number3 = 5;
System.out.println(number1==number2); //false
System.out.println(number1==number3); //true
}
}
1.引用数据类型
对于引用类型来说,==比较的是双方的内存地址,相同返回true否则返回false。
以String类型举例
public class Test10 {
public static void main(String[] args) {
String str01 = "just do it";
String str02 = "just"+" do it";
String str03 = "just";
System.out.println(str01 == str02);// true
System.out.println(str01 == str03);//false
}
}
equals()方法
1.基本数据类型没有equals()方法
2.引用数据类型
引用数据类型进行值或内容的比较,由于字符串内部是由char[] 数组存储的,所一实际上比较的是字符数组。
JDK8 String内部是由char[]保存的,但在JDK9则是用byte[]进行保存的
以String为例:
1.未重写父类Object的equals()方法
默认使用父类Object的equals方法
public boolean equals(Object obj) {
return (this == obj);
}
可以看出父类的equals方法比较的是双方的内存地址(相同返回true,否则返回false)
2.重写父类的equals()方法
以下是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;
}
String重写父类方法的逻辑:
1.首先比较双方的内存地址,相同返回true,否则向下执行。
2.其次比较双方的长度,不相同则退出if语句并返回false,相同则向下执行。
3.最后比较双方的内容,若存在不同的元素则返回false,否则继续执行,直到最后退出循环,最后返回true。
值得一提的是重写equals()方法必须重写hashCode()
首先介绍hashCode()
hashCode()
hashCode()是Object类中的native本地方法,底层通过使用C/C++来实现,用于获取对象的HashCode哈希码。
HashCode哈希码是该对象的内存地址通过哈希hash算法计算出的一个整数值,代表该对象在哈希表中的位置,作用是为了提高查找对象的快捷性,通过HashCode可以快速定位对象的存储地址。
俩个对象进行比较,先通过HashCode进行比较,若HashCode相等(俩个不同的对象hashCode可能会相同,只不过概率特别小),再调用equals()方法进行比较,以此提高效率。
重写equals()方法必须重写hashCode()
俩个对象进行比较,先通过HashCode值进行比较,若HashCode值相等,再调用equals()方法进行比较,以此提高效率。
1.如果俩个对象相同,说明它俩的hashCode值一定相同
2.如果俩个对象的hashCode相同,他们并不一定相同(所以需要使用equals进行比较),例如:字符串 “重地” 与 “通话” hashCode值相同。
public class Test11 {
public static void main(String[] args) {
String str01 = "通话";
String str02 = "重地";
System.out.println("str01的哈希码是:"+str01.hashCode());
System.out.println("str02的哈希码是:"+str02.hashCode());
}
}
运行结果:
所以,在每个equals()方法的类中,也必须覆盖hashCode()方法,否则会违反Object.hashCode的通用约定,从而导致无法结合基于散列的集合在一起正常运作,例如:HashMap,HashSet和HashTable等集合。
Object.hashCode的通用约定
- 在应用程序中,只要对象的euqals方法的比较操作所用的信息没有修改,那么对于同一个对象的调用多次hashCode,必须始终如一返回同一个哈希值。
- 如果两个对象通过equals比较相等,那么它们的哈希值相同。
- 如果两个对象通过euqals比较不等,他们的哈希值可能相同,取决于hashCode的实现,由此散列表的性能也会有区别。
以上就是==和equals()的区别、hashCode()、为什么重写equals()方法必须重写hashCode()的全部内容,如有不当请大家多多指正,一起进步!!!