首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

解释equals(),hashcode()跟==

2012-09-04 
解释equals(),hashcode()和?这是因为String类已经重写了equals()方法和hashcode()方法,所以在根据上面的

解释equals(),hashcode()和==

?

这是因为String类已经重写了equals()方法和hashcode()方法,所以在根据上面的第1.2条原则判定时,hashset认为它们是相等的对象,进行了重复添加。?
但是看下面的程序:?
import java.util.*;?
public class HashSetTest?
{?
public static void main(String[] args)?
{?
HashSet hs=new HashSet();?
hs.add(new Student(1,"zhangsan"));?
hs.add(new Student(2,"lisi"));?
hs.add(new Student(3,"wangwu"));?
hs.add(new Student(1,"zhangsan"));?

Iterator it=hs.iterator();?
while(it.hasNext())?
{?
System.out.println(it.next());?
}?
}?
}?
class Student?
{?
int num;?
String name;?
Student(int num,String name)?
{?
this.num=num;?
this.name=name;?
}?
public String toString()?
{?
return num+":"+name;?
}?
}?
输出结果为:?
1:zhangsan?
1:zhangsan?
3:wangwu?
2:lisi?
问题出现了,为什么hashset添加了相等的元素呢,这是不是和hashset的原则违背了呢?回答是:没有?
因 为在根据hashcode()对两次建立的newStudent(1,"zhangsan")对象进行比较时,生成的是不同的哈希码值,所以hashset把他当作不同的对象对待了,当然此时的 equals()方法返回的值也不等(这个不用解释了吧)。那么为什么会生成不同的哈希码值呢?上面我们在比较s1和s2的时候不是生成了同样的哈希码 吗?原因就在于我们自己写的Student类并没有重新自己的hashcode()和equals()方法,所以在比较时,是继承的object类中的 hashcode()方法,呵呵,各位还记得object类中的hashcode()方法比较的是什么吧!!?
它是一个本地方法,比较的是对象的 地址(引用地址),使用new方法创建对象,两次生成的当然是不同的对象了?(这个大家都能理解吧。。。),造成的结果就是两个对象的hashcode() 返回的值不一样。所以根据第一个准则,hashset会把它们当作不同的对象对待,自然也用不着第二个准则进行判定了。那么怎么解决这个问题呢???
答案是:在Student类中重新hashcode()和equals()方法。?
例如:?
class Student?
{?
int num;?
String name;?
Student(int num,String name)?
{?
this.num=num;?
this.name=name;?
}?
public int hashCode()?
{?
return num*name.hashCode();?
}?
public boolean equals(Object o)?
{?
Student s=(Student)o;?
return num==s.num && name.equals(s.name);?
}?
public String toString()?
{?
return num+":"+name;?
}?
}?
根据重写的方法,即便两次调用了newStudent(1,"zhangsan"),我们在获得对象的哈希码时,根据重写的方法hashcode(),获得的哈希码肯定是一样的(这一点应该没有疑问吧)。?
当然根据equals()方法我们也可判断是相同的。所以在向hashset集合中添加时把它们当作重复元素看待了。所以运行修改后的程序时,我们会发现运行结果是:?
1:zhangsan?
3:wangwu?
2:lisi?
可以看到重复元素的问题已经消除。?
关于在hibernate的pojo类中,重新equals()和hashcode()的问题:?
1),重点是equals,重写hashCode只是技术要求(为了提高效率)?
2),为什么要重写equals呢,因为在java的集合框架中,是通过equals来判断两个对象是否相等的?
3),在hibernate中,经常使用set集合来保存相关对象,而set集合是不允许重复的。我们再来谈谈前面提到在向hashset集合中添加元素时,怎样判断对象是否相同的准则,前面说了两条,其实只要重写equals()这一条也可以。
但 当hashset中元素比较多时,或者是重写的equals()方法比较复杂时,我们只用equals()方法进行比较判断,效率也会非常低,所以引入了 hashcode()这个方法,只是为了提高效率,但是我觉得这是非常有必要的(所以我们在前面以两条准则来进行hashset的元素是否重复的判断)。?
比如可以这样写:?
public int hashCode(){?
return 1;}//等价于hashcode无效?
这样做的效果就是在比较哈希码的时候不能进行判断,因为每个对象返回的哈希码都是1,每次都必须要经过比较equals()方法后才能进行判断是否重复,这当然会引起效率的大大降低。

==用于比较引用和比较基本数据类型时具有不同的功能:?
比较基本数据类型,如果两个值相同,则结果为true?
而在比较引用时,如果引用指向内存中的同一对象,结果为true?

热点排行