以java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这样:
1.new Object(),JVM根据这个对象的Hashcode值,放入到对应的Hash表对应的Key上,如果不同的对象确产生了相同的hash值,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。
2.比较两个对象的时候,首先根据他们的hashcode去hash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key上,那么他们一定在这个key上的链表上。那么此时就只能根据Object的equal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定他们不能equal.
关于内存泄露:
举例如下:
**************************************************************************************
public class Person {
@Override
public boolean equals(Object obj) {
//首先判断两个对象的内存地址是否一样,如果一样则相等
if(this==obj){
return true;
}
//如果不想等再進行以下比較
if (obj instanceof Person) {
//判断obj是否为Person类的实例,如果是的话在进行比较,如果不是则两个对象不相等
Person personObj = (Person) obj;
if (this.id == personObj.id
&& this.userName.equals(personObj.userName)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
@Override
public int hashCode() {
//还得判断null值
return userName.hashCode()+id;//此时id参与hashcode的生成
}
private int id;
private String userName;
public Person(int id, String userName) {
this.id = id;
this.userName = userName;
}
public void setId(int id) {
this.id = id;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getId() {
return id;
}
public String getUserName() {
return userName;
}
}
********************************************************************************
import java.io.*;
import java.util.Hashtable;
public class Test {
public static void main(String[] args) {
Person person1 = new Person(1, "username");
Person person2 = new Person(2, "username");
Person person3 = person1;
Hashtable ht = new Hashtable();
ht.put(person1,"aaa");
ht.put(person2,"bbb");
//person1.setId(3);//此时最好不要更改参与hashcode计算的变量的值,如果更改以后,容易造成内存泄露
//像本例,中如果执行这一句,返回结果为2,不执行这句返回结果为1
//执行这一句以后person1的hashcode值已经改变,但是本来存入hashtable中的person1的位置不会改变,所以如果想要删除person1对象,则不能实现,造成内存泄露
ht.remove(person1);
System.out.println(ht.size());
}
}
|