为什么要有hashCode,hashCode的作用?
答:当JVM每New出一个对象时,他都会将这个Obj放到哈希表中,下次比较对象或者取对象时根据hashCode获取,这样可以提高存取效率。如果发现hashCode相等,JVM会生在这个地方生成一条链表,然后调用euqals方法判断这个对象是否与链里的对象相同,若相同,则不会插入,若不同则插入。就是说,一个集合hashSet或者hashMap集合,要判断对象是否能插入集合中,就需要先判断hasnCode是否相同,若相同则在链表中调用equals方法判断是否有相同的对象,若equals都相同则插入,否则不插入。
具体流程图:
然后我们看看map.put的源码:
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
举个例子:
例如我现在有一个集合hashSet,里面有1000个元素,如果只有equals方法,我就要比较1000次才能插入对象,如果有hashCode方法,我只需在table表里这个hashCode Index是否为空的,如果空就代表没有这个元素,否则就代表有,那么这样就提高了插入的效率了。
下面是hashCode代码和equals代码参考
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
System.out.println("hashCode : "+ result);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
PS:当类没有重写equals和hashCode的方法时,默认继承Object的方法,Object的equals方法相当于 “==”.
具体参考http://blog.csdn.net/afgasdg/article/details/6889383