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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 阮金明 黑马帝   /  2011-12-31 10:36  /  4649 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 阮金明 于 2011-12-31 17:27 编辑

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

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

9 个回复

倒序浏览
一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。

hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。

要从物理上判断2个对象是否相等,用==就可以了。

所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java 使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

回复 使用道具 举报
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所回收,然而它却占用内存。

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

回复 使用道具 举报
Ojbect类的hashCode方法返回的是Object对象的内存地址。可以通过Integer.toHexString(new Object().hashCode);来得到。

当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到一个位置用来存放当前对象,挡在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接增加进去。如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象进行equals方法比较,如果该equals方法返回false,那么集合认为集合中不存在该对象,在进行一次散列,将该对象放到散列后计算出的新地址里,如果equals方法返回true,那么集合认为集合中已经存在该对象了,不会再将该对象增加到集合中了。
有一个概念,两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
hashcode是主要根据地址生成一个hash码,这个码可以帮助计算机判断是否是同一个内存中的值
回复 使用道具 举报
public int hashCode()返回该对象的哈希码值。此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。

hashCode 的常规协定是:

在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的)

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
李盈科 黑马帝 2011-12-31 16:26:42
7#
hashCode()通常和equals()方法一起重写 用来判断两个对象是否相等,hashCode方法会生成一个hash值 这个是个经验值
例如在HashSet()使用时候就会调用hashCode()方法,因为Set中的每个对象都是不同的,所以如果添加的对象与原存储的所有对象的hashCode值如果不一致,就直接加入进去,如果一直 再比较equals()方法,若返回true就不加入了,反之加入。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
付星 黑马帝 2011-12-31 16:40:18
8#
Object类中的hashCode是返回对象在内存中地址转换成的一个int值(可以就当做地址看),也就是说全局唯一的。你的实验证明了这一点。你创建的对象数组,数组里面的每个对象都不是同一个。
Java内存泄露的原因

1、静态集合类像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector等应用着。

2、内部类和外部类的引用容易出现内存泄露的问题

3、监听器的使用,java中往往会使用到监听器,在释放对象的同时没有相应删除监听器的时候也可能导致内存泄露。

4、大量临时变量的使用,没有及时将对象设置为null也可能导致内存的泄露

5、数据库的连接没有关闭情况,包括连接池方法连接数据库,如果没有关闭ResultSet等也都可能出现内存泄露的问题。

举例一个内存泄露的例子:

Vector v = new Vector(10);

for (int i = 1; i<100; i++){

    Object o = new Object();

    v.add(o);

    o = null;

}

别以为o对象被回收了,实际上v引用了这些对象,还被引用的对象GC是没有办法回收的,这样就很可能导致内存的泄露。

回复 使用道具 举报
付星 黑马帝 2011-12-31 16:48:03
9#
每个对象在内存当中的存储组织方式就是利用这种散列方式存储,当然也就有它的
hashCode了,如果想获取这个对象在Hash表中的位置,就可以调用Object.hashCode() 结果返回int型
HashSet中,在对应元素添加进set集合后,不要再去修改元素的值,否则对应元素的hashcode值发生变化,此时如果调用
集合的remove(),contains()方法,将不会得到正确的结果。remove()方法并不能正确remove掉对应的元素,造成内存泄漏。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马