hashCode()用于计算该对象的哈希值,当以哈希表为底层数据结构存储数据时,就需要用到哈希值,如HashSet,HashMap等集合容器。
hashCode() 与 equals() 为什么要一起重写呢?
通常,是基于这样的考虑:
如果该对象使用哈希表的进行存储,那么需要通过hashCode()计算哈希码,得到对象的地址,当地址相同时,就需要进一步调用该对象的equals()来比较内容是否相同。
因此,才推荐将2个方法一起重写,在使用hash结构的集合存储时,才不会出现问题。
自定义哈希值的计算方式---复写hashCode()
自定义对象是否相同的比较规则---复写equals()
对象之间的比较,可以比较地址,也可以自定义比较规则
== 比较的是对象在内存中的地址是否相同,地址相同,则对象一定相同
equals 比较的内容,由equals方法内部指定,可以比较地址(Object基类中的默认实现),也可以自定义比较规则,因此,equals方法提供了对象之间比较的扩展功能。
比如,String类复写了Object基类中的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;
}
字符串比较时,使用==与equals()进行比较的区别
public class Test {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
String objStr = new String("abc");
//字符串常量之间的比较,字符串常量在内存中只有一份,因此地址相同,所以都为true
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true
//字符串常量与堆内存中字符串的比较
System.out.println(str1==objStr);//地址不同,false
System.out.println(str1.equals(objStr));//虽然地址不同,但String类对equals方法进行了扩展,会继续比较字符串中的字符,所以true
}
}
通过复写equals(),自定义对象是否相同的比较规则
public class Person {
private String name;
public Person() {
super();
}
public Person(String name) {
super();
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/**
* 自定义Person是否相同的比较规则
*/
@Override
public boolean equals(Object obj) {
//1.对方是null,直接false
if(obj == null)
return false;
//2.类型不同,抛异常
if(!(obj instanceof Person))
throw new ClassCastException("类型不同,无法比较");
//3.地址相同,直接true
if(this == obj)
return true;
//4.最后,按自定义规则比较。(额外一步:将比较的对象向下转型为同一类型)
Person anotherPerson = (Person)obj;
//这里又利用了String类中定义的equals(),比较字符串是否相同
return this.name.equals(anotherPerson.name);
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person("zs");
Person p2 = p1;
Person p3 = new Person("ls");
Person p4 = new Person("zs");
//对方为null:false
System.out.println(p1.equals(null));
//地址相同:true
System.out.println(p1.equals(p2));
//地址不同,内容不同:false
System.out.println(p1.equals(p3));
//虽然地址不同,但是内容相同:true
System.out.println(p1.equals(p4));
}
}