先看下百科对HashCode的解释:
1:Object类的hashCode.返回对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。
2:String类的hashCode.根据String类包含的字符串的内容,根据一种特殊算法返回哈希码,只要字符串所在的堆空间相同,返回的哈希码也相同。
3:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new
Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
1.两个对象equals相等那么hashcode 是一定相等的。
2.两个对象equals不相等hashcode可能相等可以不相等。
因为hashCode说白了是地址值经过一系列的复杂运算得到的结果,而Object中的equals方法底层比较的就是地址值,所以equals()相等,hashCode必定相等,反equals()不等,在java底层进行哈希运算的时候有一定的几率出现相等的hashCode,所以hashCode()可等可不等。
通过对于这两个方法的使用: equals和hashcode,在set 集合框架中体现是最突出了。
这两个方法的调用原则是: 一、先去调用hashcode方法比较,如果相等的情况下再去调用equals方法比较,这时equals相等那边认为是同一个对象,则不同对象。二、先去调用hashcode方法不相等了,这样就不会去调用equals方法做比较的。所以,我们在写程序时一般会重写这两个方法。
public class Hello {
public static void main(String[] args) {
/**
* 重写equals时对象的相同与否是根据自身的需求进行判定
* 下面用户例子中,我们认为一个用户是否为同一个根据用户的name进行判定。
* 如果用户姓名一样则判定两个对象为同一个用户。
*/
User u1=new User(1,"a");
User u2=new User(1,"a");
/**
* 这两个方法的调用原则是: 一、先去调用hashcode方法比较, (如果两个用户的name属性相同,则hashcode相同)
* 如果相等的情况下再去调用equals方法比较
* 这时equals相等那边认为是同一个对象,则不同对象。
* 二、先去调用hashcode方法不相等了,这样就不会去调用equals方法做比较的。
* 所以,我们在写程序时一般会重写这两个方法。
*/
System.out.println(u1+":"+u1.hashCode());
System.out.println(u2+":"+u2.hashCode());
System.out.println(u1.equals(u2));
运行结果:
User@61:97
User@61:97
true
}
}
运行
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public User() {
super();
}
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof User) {
User users = (User) obj;
/**
* 我们认为一个用户姓名相同就判定为同一个用户
*/
if (this.getId() == users.getId() && this.getName().equals(users.getName())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
/**
* 在hashCode中返回他们name字段的HashCode值,
* 如果两个参数的name相同则HashCode一定相同(两个对象equals相等那么hashcode 是一定相等的。)
* 如果HashCode不同则判定两个对象不相同。
*/
return this.getName().hashCode();
}
}