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; }