HashSet判断加入的对象是否重复的原理:
对于Set接口的实现类HashSet,它是按照哈希算法来存取集合中的对象,并且因为其继承了Set接口,所以不允许插入相同的数据。那么它如何来保证不插入相同的数据,这就要使用到equals()和hashCode()方法了。在我们往HashSet里面添加对象(add()方法里的参数都是对象)的时候,在Add()的方法内部,它首先调用该对象的hashCode()方法(hashCode方法用来计算该对象的哈希码),如果返回的哈希码与集合已存在对象的哈希码不一致,则add()方法认定该对象没有与集合中的其它对象重复,那么该对象将被添加进集合中。如果hashCode()方法返回的哈希码与集合已存在对象的哈希码一致,那么将调用该对象的equals方法,进一步判断两个对象是否相等。之所以在进行了hashcode(哈希码)的比较后,又调用equals()方法进行比较,是因为虽然HashSet采用的是通过hashcode来区分对象,但是在java中hashcode会重码(即不同的对象,其hashcode可能会相同)
在hibernate中,为什么要实体类重写这两个方法?
a.一般实体类是多的一方
b.判断这样的两个对象是相等的,不让它们重复加入
如:有一个类
public class Comment {
/**
* @param args
*/
private Long id ;
private String name ; //comment 人的名字
private Date createDate ;
private String content;
public Comment(String name,Date createDate,String content) {
this.name=name;
this.createDate =createDate;
this.content = content;
}
根据需求,不允许这样的对象添加到hashset中,只允许一个
Comment d1 = new Comment("wind",date,"abbb");
Comment d2 = new Comment("wind",date,"abbb");
Comment d3 = new Comment("wind",date,"ab");
在类中重写方法就行了,如下
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj)
{
return true;
}
if (!(obj instanceof Comment)) {
return false;
}
Comment other = (Comment) obj;
if (getName()!=null && getName() .equals(other.getName())&& getCreateDate()!=null && getCreateDate().equals(other.getCreateDate())) {
return true;
} else {
return false;
}
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((getName() == null) ? 0 : getName().hashCode());
result = PRIME * result + ((getCreateDate() == null) ? 0 : getCreateDate().hashCode());
return result;
}
选择那个属性进行比较,要看你的系统的业务需求,一定要从业务需求里找比较属性
为什么要选择name 和 createDate 这两个属性,在这里我们假设有这样一个业务,有一个人在某个时间写了评论,评论是Comment类,name 是这个人的名字,写作时间是createDate ,这两个的组合一定是唯一的,一个人不可能在同一个时间写下两篇文章,我们就选这样的组合做为比较,这样才符合业务的需求。
测试代码:
Set s = new HashSet();
Date date = RefleshActionHelper.FormatDate("2004-05-09", "yyyy-mm-dd");
Comment d1 = new Comment("wind",date,"abbb");
Comment d2 = new Comment("wind",date,"abbb");
s.add(d1);
s.add(d2);
System.out.println(d1.hashCode()+" "+d2.hashCode());
Iterator it =s.iterator();
while (it.hasNext()){
Comment t= (Comment)it.next();
System.out.println(t.getName());
}
结果是只添加了一个
上面比较的都是对象,如果比较基本类型呢,如,一个int count;我们在hashCode() 里这样写,基本类型是不能获得hashCode()方法的,直接加它的属性值就行了
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + count
result = PRIME * result + ((getCreateDate() == null) ? 0 : getCreateDate().hashCode());
return result;
}