hash
了解 hashCode() 之前最好先了解一下 hash
hashCode() 和 equals()
hashCode() 和 equals() 的作用都是用来比较两个对象是否相等,hashCode() 是通过将对象的内部地址(物理地址)转换成一个整数,然后将这个整数通过hash函数的算法返回一个 hashcode,再比较时通过比较 hashCode 来判断对象是否相等,因此在效率上,hashCode() 的效率是大于 equals() 的,但是 hashCode() 可能会发生 hash冲突,导致有时候值不同,而 hashCode 是相同的,因此在准确度上,equals() 的准确度大于 hashCode()。由此,我们可以得出两条结论:
-
如果两个对象通过 equals() 判读出相等,那么这两个对象的 hashCode 一定也相等。
-
如果两个对象的 hashCode 相等,这两个对象不一定相等。
由这两个结论,可以得出推论:如果两个对象的 hashCode 不相等,那么这两个对象一定不相等。因此在实际运用中,我们可以先用 hashCode() 去进行对比,如果 hashCode 不等,则两个对象不相等,如果 hashCode 相等,我们再调用 equals() 进行深度对比。这样既能保证效率,又能保证精准。
在集合类中的使用建议
Java 的集合类分为 List,Set,Map 三种,List 集合是有序集合,允许存在相同项;Set 集合是无序集合,不允许重复;Map 集合是键值对,键不允许重复,但是值可以允许重复。对于 Set 集合和 Map 的键这种不允许重复的,我们必须要重写 hashCode() 和 equals() 方法。
举例,看以下代码:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
User user1 = new User(1, "yin", "123123");
User user2 = new User(1, "yin", "123123");
Set set=new HashSet();
set.add(user1);
set.add(user2);
Map<User, Integer> map = new HashMap<>();
map.put(user1, 1);
map.put(user2, 1);
//判断 user1 的内容是否和 user2 的相等
System.out.println(user1.equals(user2));
//user1的 hashCode
System.out.println(user1.hashCode());
//user2的 hashCode
System.out.println(user2.hashCode());
//Set集合的元素个数
System.out.println(set.size());
//Map集合的元素个数
System.out.println(map.size());
}
}
该代码返回的结果是:
false
366712642
1829164700
2
2
不难看出,虽然两个 User 对象元素的值相等,但是两个 User 对象却不相等。因此,若想要俩个相等,就得重写 hashCode() 和 equals() 方法。
//用户类
public class User {
//用户id
private int user_id;
//用户昵称
private String user_name;
//用户密码
private String password;
public User(int user_id, String user_name, String password) {
super();
this.user_id = user_id;
this.user_name = user_name;
this.password = password;
}
@Override
public boolean equals(Object obj) {
//与类本身相同
if(obj == this) {
return true;
}
//强制转换
User user = (User) obj;
//判断元素是否相等
if(user_id == user.user_id && user_name.equals(user.user_name) && password.equals(user.password)) {
return true;
}
return false;
}
@Override
public int hashCode() {
//按自己的方式生成一个 hashCode
return user_id + user_name.hashCode() * password.hashCode();
}
}
运行结果:
true
-138521983
-138521983
1
1
参考:equals()和hashCode()方法在集合类set中的使用 - 锟斤拷锟斤拷 - 博客园 (cnblogs.com)