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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周洋 黑马帝   /  2012-4-2 16:05  /  2327 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

HashSet 保证元素唯一性
                        是通过元素的两个方法:hashCode和equals来完成
                        如果元素的HashCode值相同,才会判断equals是否为true
                        如果元素的HashCode值不同,不会调用equals

此处的HahCode值如何判断?复写hashCode方法的代码,nme.hashCode()是什么意思?

public int hashCode()

        {

                System.out.println(this.name+"...hashCode");

                return name.hashCode()+age*39;

        }

5 个回复

倒序浏览
   name.hashCode是调用了name的哈希值,为什么要调用呢?是因为同时出现两个人的年龄相同时,这时就要判断姓名是否相同,而姓名是字符串型的,hashCode的返回值是int型的,所以就要将name转成int型直接调用name的哈希值加上年龄就OK了。

至于乘以39是为什么呢?这是特殊情况,举个例,假如有两个人,一个张三40岁,一个李四20岁,算出来的哈希值恰好相同,就有一个人就存不进去,明明这两个人却姓名不一样,年龄也不一样,这时候让年龄乘以一个数就整数,这个整数就可以随便定义,但是这个数不能过大或者是1,过大会超出int型范围,等于1结果还是一样,就白乘了。

其实应该把这个整数修饰为常量。

public int hashCode()
         
        {
           final int NUMBER = 39;
                               return name.hashCode()+age*NUMBER;

        }
回复 使用道具 举报
  还有为什么要复写hasCode方法,是这样的,如果你定义了一个person类,你同时存入两个人姓名为“张三”年龄为24岁,结果发现这两个人都能够存进去,这是为什么呢?它因为默认Object走的是系统,算的是地址哈希值,这两个元素的地址肯定不一样,这样算出来的哈希值就不一样,所以两个相同的元素都存进去了。
回复 使用道具 举报
关于hashCode的一些体会 当我们向hashSet或者hashMap中放入数据(对象)的时候,hashSet或者hashMap底层代码会根据放入的对象身上的hashCode()方法(继承自Object对象)以最优的方法(这里的计算用到了一些算法)计算出该对象应该放入的位置,我们姑且认为这个位置就是放入数据(对象)的hash码,这种计算数据(对象)hash码的算法会根据这些对象的特点把这些对象进行归类,归类也就是把具有相同特点(根据具体算法)的对象赋予相同的哈希码;hashSet或者hashMap中的这些数据其实就是一个个的Entry对象,每个Entry对象都被赋予了唯一的哈希码,具有相同哈希码的Entry对象将在同一个Entry链上;其实hashMap是用数组和链表共同实现的,数组上放着不同哈希码的Entry对象,数组上的每一个Entry对象就是Entry链表的表头,后来的Entry对象将会根据其本身的哈希码值和数组上的这些Entry对象的哈希码值比较,当在数组上找到与之相同的Entry对象时,该对象就会和数组中的Entry对象组成链表(注意,这个对象将会作为链表的表头),按照这个规律,相同哈希码的Entry对象将在同一个Entry链上,如果后来的Entry对象的哈希码在数组中没有找的匹配的哈希码,那么这个Entry对象将在数组中找一个位置(当数组空间不够的时候会自动的扩容)。



        每一个对象(数据)的哈希码由该对象身上的hashCode()方法决定,而对于equals()方法,Object的eqals()方法会根据对象的内存地址比较对象,我们也可以Override(覆盖)Object的该方法,打破这种用对象内存地址比较的机制,hashCode()方法和equals()方法应该
回复 使用道具 举报
由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数,这样既使两个对象的内部数据相同,如果没有复写 hashCode 方法,该方法也可能返回不同的值,这样与现实中直观的看法相悖,为了把内部数据相同就理解为是同一个实体(或者说是对象),需要复写 hashCode 方法,比如说 Student 类,其中有两个字段 name 和 age ,如果这两个字段相同就理解为同一个对象,应该把 hashCode 的方法体与这两个字段挂钩,使之如果这两个字段相同就使 hashCode 的返回值相同。
name 应该是一个String类型吧,那么name.hashCode()调用的是String类的 hashCode 方法,该方法返回的是name的哈希值
回复 使用道具 举报
public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是:

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


返回:
此对象的一个哈希码值。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马