hashcode即哈希值,哈希值的作用就是用于在哈希表中查找指定的元素,通过哈希值去定位该元素。
大家一般在做对象比较的时候,都会重写equals方法,那么根据约定,重写equals方法的同时,必须重写hashcode方法,否则哈希表将用不了了。
直接通过代码给大家解释吧:
class Person {
private int age;
private String userName;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Person(int age, String userName) {
super();
this.age = age;
this.userName = userName;
}
}
Person p1 = new Person(10, "a");
Person p2 = new Person(11, "b");
System.out.println(p1);
System.out.println(p2);
hashcode.Person@600c199f
hashcode.Person@3a6646fc
可以看到该对象的hashcode哈希值,这里是调用Object的hashcode方法,该方法是native的,表示的是该对象的内存地址。
这两个对象目前肯定是不相等的。
Person p1 = new Person(11, "b");
Person p2 = new Person(11, "b");
System.out.println(p1);
System.out.println(p2);
hashcode.Person@29e07d3e
hashcode.Person@513e86ec
这样呢,还是不相等。
重写equals方法
public boolean equals(Object obj) {
if(this==obj) {
return true;
}
if(obj instanceof Person) {
Person p = (Person)obj;
if(p.getAge()==this.getAge()&&p.getUserName().equals(this.getUserName())) {
return true;
}
}
return false;
}
Person p1 = new Person(11, "b");
Person p2 = new Person(11, "b");
System.out.println(p1);
System.out.println(p2);
System.out.println(p1.equals(p2));
hashcode.Person@3a6646fc
hashcode.Person@10be6858
true
重写equals方法比较了对象中两个属性来判断对象是否相等,但是本质上还是两个对象。
这时,我们将对象放到哈希表中看看:
Map<Person,String> map = new HashMap<Person,String>();
map.put(new Person(13, "c"), "p3");
map.put(new Person(14, "d"), "p4");
System.out.println(map.get(new Person(13, "c")));
System.out.println(map.get(new Person(14, "d")));
null
null
虽然也重写了equals方法了,虽然map的put和get的key是相等的对象了,但是get出来的仍然是null。
map在put完后内容如下:
{hashcode.Person@4aa168c=p3, hashcode.Person@3aae43b8=p4}
get的时候key如下:
hashcode.Person@4d4bb075
hashcode.Person@d98c113
从以上内容来看,压根就不是同样的key,所以当然取不出来内容了,现在我们再来重写hashcode方法:
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.getAge()+this.getUserName().hashCode();
}
p3
p4
这就从map中取到你刚刚放进去的内容了。
想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
所以hashcode方法让你找到了这个桶,然后equals方法让你在桶里找到了那个元素。
HashMap其实就是数组链表,put操作的时候,通过key的hashcode去运算得到index方法数组中某个位置,这样就找到了要存储的位置了,然后判断该位置上有没有元素Entity(key,value,next),是否替换等等。
出现冲突呢,该元素将永远放在该位置的链表的首位。