黑马程序员技术交流社区
标题:
hashCode方法是多此一举吗
[打印本页]
作者:
lzw123451
时间:
2013-2-25 14:20
标题:
hashCode方法是多此一举吗
我们知道
HashSet底层结构是哈希表
HashSet是通过元素的两个方法,hashCode盒equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals.
定义一个Student类
class Student
{
String name;
int age;
Student(String name,int age)
{
this.name=name;
this.age = age;
}
public int hashCode()
{
return name.hashCode()+age*37;
}
public boolean equals(Object obj)
{
if(!(Obj instanceof Student))
return false;
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age == s.age;
}
}
这个类覆盖了Object类的 hashCode和equals方法
我的问题是 既然hashCode的返回值是根据对象的属性name和agel来确定的,也就是说只要这两个属性相等hashCode返回值就相等,
那么这样在hashSet中直接判断equals方法就可以确定他们是不是同一个元素了,hashCode方法不是多此一举吗?
作者:
黑马刘杰
时间:
2013-2-25 14:33
本帖最后由 黑马刘杰 于 2013-2-25 14:35 编辑
可以这么说hashCode指向内存地址,我们的对象输出的就是经过hashCode运算后的内存地址。
equals用于比较两个对象是否相同不是只看内存地址是否相同。
Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同
你重写了equals,比较的是对象保存的内容,这样子就会出现equals一样,hashCode不同的对象了
作者:
胥文
时间:
2013-2-25 14:34
当此equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码
作者:
夏振博
时间:
2013-2-25 14:37
本帖最后由 夏振博 于 2013-2-25 14:43 编辑
1.获取元素的哈希码值(使用元素的hashCode()方法);
2.通过哈希码值计算桶位(可以把哈希码值理解为就是桶位);
3.遍历桶中元素,使用元素的equals()方法,验证元素是否在桶中已经存在;
存在则添加失败,否则把元素添加到桶中
分别添加"abc"和"cba"计算的哈希码值相同,但是它们的元素是相同的吗?这需要再次判断!
你的代码里name.hashCode()+age*37;
假如:name.hashCode()计算得12345,age*37计算得54321,相加的66666.
再添加元素计算name.hashCode()计算得54321,age*37计算得12345,相加也是得66666,
它们的返回值都是相同的,但是两个name和age是不同的,这就需要再次使用equals()判断
作者:
Gaara
时间:
2013-2-25 14:50
本帖最后由 张文彬 于 2013-2-25 14:52 编辑
其实这是根据HashSet的取值规律的,实际上当程序向HashSet集合中添加元素时,HashSet会根据该元素的hashCode值来计算他的存储位置,也就是说,每个元素的hashCode值就可以决定他的存储“索引”(HashSet本身没有索引)
//类A的equals方法总是返回true,但没有重写其hashCode()方法
class A
{
public boolean equals(Object obj)
{
return true;
}
}
//类B的hashCode()方法总是返回2,且有重写其equals()方法
class B
{
public int hashCode()
{
return 2;
}
public boolean equals(Object obj)
{
return true;
}
}
public class HashSetTest
{
public static void main(String[] args)
{
HashSet books = new HashSet();
//分别向books集合中添加两个A对象,两个B对象
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
System.out.println(books);
}
}
复制代码
结果
未命名.jpg
(12.93 KB, 下载次数: 45)
下载附件
2013-2-25 14:51 上传
这个例子就可以说明即使A对象通过equals()方法比较返回true,但HashSet依然把它们当成两个对象。
也就是说两个方法必须都重写。
作者:
Gaara
时间:
2013-2-26 14:25
这个帖子 求加技术分啊 我都好久没加过了。。。。。。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2