参考:
hashCode()和equals()的区别
在Java中任何一个对象都具备hashCode()方法和equals(Object obj)方法。
equals(Object obj)方法是用来判断两个对象是否相同,相同就返回true,不相同就返回false。
hashCode()方法返回一个int数值。
hashCode()方法的返回值和equals()方法的关系如下:
- 1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
- 2、如果两个对象不equals,他们的hashcode有可能相等。
- 3、如果两个对象hashcode相等,他们不一定equals。
- 4、如果两个对象hashcode不相等,他们一定不equals。
若重写equals(Object obj)方法,有必要重写hashcode()方法,
确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。
简单点就是:“如果两个对象相同,那么他们的hashcode应该相等”。
不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true
而hashcode()返回两个不相等的值,编译和运行都是不会报错的。
不过这样违反了Java规范,程序也就埋下了BUG。
如果equals(Object obj)返回false,即两个对象“不相同”,
并不要求对这两个对象调用hashcode()方法得到两个不相同的数。
简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。
能用hashcode判断对象相等吗?
不可以
我们可以通过调用对象的hashCode()方法来生成hashCode值。
因为两个不同的对象调用hashCode()方法生成的哈希值有可能一样,
所以不能通过哈希值相等来判断两个对象相等。
为什么要同时有hashCode()方法和equal()方法?
hashCode()方法和equal()方法的作用其实一样,
在Java里都是用来对比两个对象是否相等一致,
那么equal()既然已经能实现对比的功能了,为什么还要hashCode()呢?
因为重写的equal()里一般比较的比较全面比较复杂,这样效率就比较低,
而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,
效率很高,那么hashCode()既然效率这么高为什么还要equal()呢?
因为hashCode()并不是完全可靠,
有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),
所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:
1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
所有对于需要大量并且快速的对比的话如果都用equal()去做显然效率太低,
所以解决方式是,每当需要对比的时候,
首先用hashCode()去对比,如果hashCode()不一样,
则表示这两个对象肯定不相等(也就是不必再用equal()去再对比了),
如果hashCode()相同,此时再对比他们的equal(),如果equal()也相同,
则表示这两个对象是真的相同了,这样既能大大提高了效率也保证了对比的绝对正确性!
参考:
哈希码
哈希码是一种算法,它的目的是让同一个类的对象按照自己不同的特征尽量地有不同的哈希码,但是,不表示不同的对象哈希码完全不同。也可能有相同的情况。在Java中,哈希码代表对象的特征。
hashCode
在Java中,hashCode是jdk根据对象的地址或者字符串或者是数字算出来的int类型的数值。
常见的哈希码的算法有:
1:Object类的hashCode :
返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode :
根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串内容相同,返回的哈希码也相同。
3:Integer类 :
返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。
示例
public class Test {
public static void main(String[] args) {
//Object类的hashCode.返回对象的内存地址经过处理后的结构,
// 由于每个对象的内存地址都不一样,所以哈希码也不一样。
Object o1 = new User("1");
Object o2 = new User("2");
Object o3 = new User("1");
System.out.println("o1========" + o1.hashCode());
System.out.println("o2========" + o2.hashCode());
System.out.println("o3========" + o3.hashCode());
//o1========1975012498
//o2========1808253012
//o3========589431969
//String类的hashCode.根据String类包含的字符串的内容,
// 根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。
String s1 = "qq";
String s2 = "pp";
String s3 = "qq";
System.out.println("s1========" + s1.hashCode());
System.out.println("s2========" + s2.hashCode());
System.out.println("s3========" + s3.hashCode());
//s1========3616
//s2========3584
//s3========3616
//Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,
// 例如Integer i1=new Integer(100),i1.hashCode的值就是100 。
// 由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
Integer i1 = 88;
Integer i2 = 999;
Integer i3 = 88;
System.out.println("i1========" + i1.hashCode());
System.out.println("i2========" + i2.hashCode());
System.out.println("i3========" + i3.hashCode());
//i1========88
//i2========999
//i3========88
}
private static class User{
private String name;
public User(String name) {
this.name = name;
}
}
}