A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘晓康 中级黑马   /  2012-4-5 20:15  /  2899 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

hashcode的作用是什么?内存泄露跟它有什么关系

3 个回复

倒序浏览
hashcode是一个引用,每一个hashcode都指向一个对象,具体的作用就是用一个hashcode代表一个对象地址
方便对象传递与调用。
回复 使用道具 举报
以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());
}
}
回复 使用道具 举报
拷的,希望共同学习:
1.hashCode()方法使用来提高Map里面的搜索效率的,Map会根据不同的hashCode()来放在不同的桶里面,Map在搜索一个对象的时候先通过hashCode()找到相应的桶,然后再根据equals()方法找到相应的对象.要正确的实现Map里面查找元素必须满足一下两个条件:
(1)当obj1.equals(obj2)为true时obj1.hashCode()   ==   obj2.hashCode()必须为true
(2)当obj1.hashCode()   !=   obj2.hashCode()为true时obj.equals(obj2)必须为true

2.一个类实现Comparable接口是用来决定该类对象的自然顺序,这样把该类对象放入TreeSet,TreeMap,时会根据该类对象的自然顺序自动进行排序,另外往Queue里面存的时候也会根据对象自然顺序排序

3.光实现Comparable只能决定该类对象自然顺序,但是很多时候需要自定义排序规则,那么就要实现
Comparator接口,例如一个People实现了Comparable接口并且定义自然顺序为按照名字字母顺序排序,那么把People存到List里面的时候可以用Collections.sort()方法根据自然顺序对该List进行排序,问题就在于我现在要把People按照年龄排序该怎么办呢?一个类实现了Comparable只能重写compareTo()方法一次,那么也只能有一种顺序--自然顺序,但是为了可以用age大小排序这个List的话,就必须使用一个类实现Comparator并且重写compare()方法,定义按照age排序的规则,然后调用Collections   的   static   <T>   void   sort(List <T>   list,   Comparator <?   super   T>   c)   这个方法来按照指定比较器规定的顺序来对List排序
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点,首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;其次,这些对象是无用的,即程序以后不会再使用这些对象。如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马