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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘真 中级黑马   /  2012-7-31 22:38  /  1817 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

不知道应该怎样重写hashcode()方法呢?有什么判断标准吗?

评分

参与人数 1黑马币 +10 收起 理由
杨志 + 10 去看看别人的帖子!有很多的!.

查看全部评分

6 个回复

倒序浏览
本帖最后由 李志广 于 2012-7-31 22:58 编辑

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

hashSet集合中存入自定对象保证唯一性的代码体现为:
这是毕老师在视频中讲到的例子
public int hashCode()
                {
                        return name.hashCode()+age*2;
                }
        public boolean equals(Object obj)
                {
                if(!(obj instanceof Person))
                        return false;
                Person p=(Person)obj;
                return this.name.equals(p.name)&&this.age==p.age;
                }
希望对你有所帮助!!!!!!!!!!{:soso_e100:}

评分

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

查看全部评分

回复 使用道具 举报
重写equals方法一定要重写hashCode方法,虽然对于一个容器里存放比较少的对象来说,重写hashCode方法好像并不怎么有用,但是,当你的某个容器里存放了许许多多的对象时,重写hashCode方法的优势是明显的。因为当你要比较两个对象时,首先会调用hashCode方法,当两个对象的哈希码不同时,不用再调用equals方法也能肯定这两个对象不同,也就是说不用把你拿到的那个对象和你容器里的每个对象都equals一遍,当两个对象的哈希码相同时才会调用equals方法,而这时这个哈希桶里的对象可能只有那么几个,只需要equals那么几下就能很快的得出结果。这样能大大加快你的检索速度,提高你程序的效率。

回复 使用道具 举报
本帖最后由 焦晨光 于 2012-7-31 23:12 编辑

首先hashcode是一种编码方式,在Java中,每个对象都会有一个hashcode
Java可以通过这个hashcode来识别一个对象
在java中equals()相等的两个对象,hashcode()一定相等

一般情况下equals()和hashCode()两个函数是不用考虑的,直接使用其默认设计就行了
但是,特殊情况下,当一个对象被加入收集对象(collection object)时,这两个函数必须自己设计。

hashcode()复写判断标准:
如果对象重写了equals(Object o),不同时重写hashcode(),
可能出现2个对象相等(equals)但hashcode却不相同,这个时候就需要重写hashcode()了

注意:在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的
因此,hashCode和equals需要一起被重写

个人看书粗浅的理解!

评分

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

查看全部评分

回复 使用道具 举报
本帖最后由 贾成龙 于 2012-7-31 23:10 编辑


在集合中其实hashcode()一般是和equlas()同时应用来保证元素的唯一性的,hashcode底层用的是哈希值。
覆盖方法:以一个人的姓名和年龄为例
public int hashcode()
{
  final int NUMBER=38;
return name.hashcode()+age*NUMBER;
}

a.jpg (102.92 KB, 下载次数: 48)

a.jpg

a.jpg (102.92 KB, 下载次数: 44)

a.jpg

评分

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

查看全部评分

回复 使用道具 举报
boolean equals(Object obj)  指示其他某个对象是否与此对象“相等”。
int hashCode() 返回该对象的哈希码值。
这2个方法都是类Object中的方法,因为所有的对象都在内存中都有哈希码值,
并且对象默认的哈希码值都是不同的,而若是默认的比较方式不是所需求的时,则可以重写hashCode()与equals()方法,
拿集合HashSet来说,因为Set集合要保证元素是唯一的,而若在集合中存的是学生对象时,因为学生都具有姓名跟年龄的属性,
而如果2个年龄与姓名一致的学生对象,而他们默认的哈希码值不一样,HashSet集合会认为这是2个不同的对象,
此时可以在学生类中重写 hashCode()与equals()方法,按照自己想要的比较方式去描述学生对象,
class Student
{
        private String name;
        private int age;
        Student (String name,int age)
        {
                this.name=name;
                this.age=age;
        }
        public int hashCode()
        {
                return name.hashCode()+age*99;
        }
        public boolean equals(Object obj)
        {
                if (obj instanceof Student)
                {
                        Student s=(Student)obj;
                        return this.name.equals(s.name) && this.age==s.age;
                }
                else
                {
                        return false;
                }
        }
若2个对象的哈希码值不同则不会调用equals方法,若相同,则会调用equals方法来判断2个元素是否相同从而保证了元素的唯一性。
回复 使用道具 举报
楼上的几位已经把hash集合的原理和使用方法讲述的很详细了,这里我补充一点自己觉得很重要的,
内存泄露:
一个对象被存储进HashSet集合以后,就不能修改这个对象中的那些参与计算哈希值的字段了,
否则对象修改后的哈希值与最初存储的进HashSet集合中的哈希值就不同了,所以查找的不再是同
一个区域,这种情况下,即使在contains方法下用该对象的引用作为参数去HashSet集合中检索对象,
也将返回找不到对象的结果,这也会导致无法从HashSet集合中无法单独删除当前对象,从而导致内存泄露
我想这应该是搞开发的时候加倍注意和避免的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马