先读读网上这段话:
1,哈希算法:这种算法将集合分为若干个区域,每个对象可以计算出一个哈希码,可以讲哈希码分组,每组分别对应一个区域,根据一个对象的哈希码就可以确定这个对象存储在那个区域,从而大大提高了存储和读取兑取集合中对象的速度;
2,哈希集合:就是内部采用了哈希算法的集合,HashSet就是一种哈希集合。
3,只有类的实例对象要被采用哈希算法进行检索与存储时菜要求覆盖HashCode方法。当然提供一个hashcode方法即使对象不用到也不会有什么坏处;
4,注意:①一般来说两个对象equal方法相等时他们的哈希码必须相等,但反之则不一定;
②当一个对象被存储进哈希集合钟以后就不能修改这个对象中参与了哈希码计算的字段了,否则修改后的哈希值跟存储时的哈希值就不一样了,那么当以后需要检索这个对象时根据新的哈希码就检索不到此对象,而想要移除这个对象时也会无法删除这个对象,从而造成内存泄露;
下边是代码样例:
public class Employee {
private String name ;
private String boss;
public Employee(String _name) {
name = _name;
}
public Employee(String _name,String _boss) {
name = _name;
boss = _boss;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBoss() {
return boss;
}
public void setBoss(String boss) {
this.boss = boss;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((boss == null) ? 0 : boss.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (boss == null) {
if (other.boss != null)
return false;
} else if (!boss.equals(other.boss))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
测试代码:
import java.util.Collection;
import java.util.HashSet;
public class HashTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Employee e1 = new Employee("张三", "李四");
Employee e2 = new Employee("李大嘴", "吕秀才");
Employee e3 = new Employee("张三", "李四");
Collection collection = new HashSet();
collection.add(e1);
collection.add(e2);
collection.add(e3);
e2.setName("李小嘴");
//由于重算了hashcode,e2的内存地址已经不是原先的内存地址了,这里也就无法移除e2,这就会导致内存泄露
collection.remove(e2);
System.out.println(collection.size());//输出还是2
}
}
重写equals必须重写hashcode算法,如果仅重写equals,如果你new出两个对象,其实两个对象是相等的,但是Object的hashCode是=操作,即比较地址,很显然,两个对象的内存地址是不一样的,hash值肯定不同,但是两个对象却是是相同的,所以这是你必须重写Object的hashCode方法。