黑马程序员技术交流社区
标题: hashcode()怎么运用? [打印本页]
作者: 刘真 时间: 2012-7-31 22:38
标题: hashcode()怎么运用?
不知道应该怎样重写hashcode()方法呢?有什么判断标准吗?
作者: 李志广 时间: 2012-7-31 22:55
本帖最后由 李志广 于 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:}
作者: 黄锐 时间: 2012-7-31 23:02
重写equals方法一定要重写hashCode方法,虽然对于一个容器里存放比较少的对象来说,重写hashCode方法好像并不怎么有用,但是,当你的某个容器里存放了许许多多的对象时,重写hashCode方法的优势是明显的。因为当你要比较两个对象时,首先会调用hashCode方法,当两个对象的哈希码不同时,不用再调用equals方法也能肯定这两个对象不同,也就是说不用把你拿到的那个对象和你容器里的每个对象都equals一遍,当两个对象的哈希码相同时才会调用equals方法,而这时这个哈希桶里的对象可能只有那么几个,只需要equals那么几下就能很快的得出结果。这样能大大加快你的检索速度,提高你程序的效率。
作者: 焦晨光 时间: 2012-7-31 23:06
本帖最后由 焦晨光 于 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需要一起被重写
个人看书粗浅的理解!
作者: 贾成龙 时间: 2012-7-31 23:06
本帖最后由 贾成龙 于 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, 下载次数: 55)
-
a.jpg
(102.92 KB, 下载次数: 52)
作者: 潘星 时间: 2012-8-7 01:40
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个元素是否相同从而保证了元素的唯一性。
作者: 徐帅 时间: 2012-8-7 08:19
楼上的几位已经把hash集合的原理和使用方法讲述的很详细了,这里我补充一点自己觉得很重要的,
内存泄露:
一个对象被存储进HashSet集合以后,就不能修改这个对象中的那些参与计算哈希值的字段了,
否则对象修改后的哈希值与最初存储的进HashSet集合中的哈希值就不同了,所以查找的不再是同
一个区域,这种情况下,即使在contains方法下用该对象的引用作为参数去HashSet集合中检索对象,
也将返回找不到对象的结果,这也会导致无法从HashSet集合中无法单独删除当前对象,从而导致内存泄露
我想这应该是搞开发的时候加倍注意和避免的。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |