序
項目里有一個取數(shù)據(jù)的算法巫玻,返回List<Vo>這樣的集合祠汇,返回的集合要求沒有重復的對象且按發(fā)布時間做排序。
第一時間想到TreeSet這個數(shù)據(jù)結構诗力。
一我抠、對自定義對象去重
重寫自定義對象的equals 和 hashCode方法
SUN官方的文檔中規(guī)定
如果重定義equals方法,就必須重定義hashCode方法,以便用戶可以將對象插入到散列(哈希)表中
那么 SUN 公司是出于什么考慮做了這個規(guī)定呢瓣窄?
在集合框架中的HashSet纳鼎,HashTable和HashMap
都使用哈希表的形式存儲數(shù)據(jù)裳凸,而hashCode計算出來的哈希碼便是它們的身份證登舞。
哈希碼的存在便可以:
- 1.快速定位對象悬荣,提高哈希表集合的性能。
- 2.只有當哈希表中對象的索引即hashCode和對象的屬性即equals同時相等時践叠,才能夠判斷兩個對象相等嚼蚀。
- 3.從上面可以看出,哈希碼主要是為哈希表服務的弄捕,其實如果不需要使用哈希表导帝,也可以不重寫hashCode。
- 4.但是SUN公司應該是出于對程序擴展性的考慮(萬一以后需要將對象放入哈希表集合中)斋荞,才會規(guī)定重寫equals的同時需要重寫hashCode虐秦,以避免后續(xù)開發(fā)不必要的麻煩。
重寫equals的注意事項
Java語言規(guī)范要求equals需要具有如下的特性:
自反性:對于任何非空引用 x蜈彼,x.equals()應該返回true俺驶。
對稱性:對于任何引用 x 和 y,當且僅當y.equals(x)返回true秉颗,x.equals(y)也應該返回true送矩。
傳遞性:對于任何引用 x、y 和 z菇怀,如果x.equals(y)返回true,y.equals(z)
也應返回同樣的結果爱沟。
一致性:如果 x 和 y 引用的對象沒有發(fā)生變化,反復調用x.equals(y)
應該返回同樣的結果身冀。
對于任意非空引用 x括享,x.equals(null) 應該返回false。
更多詳細的說明請參考
Java 重寫 equals 與 hashCode 的注意事項
這里我需要以主鍵文章ID為準來去重剩愧,對TopicVO對象復寫hashCode和 equals方法:
@Override
public int hashCode()
{
return topicId.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof TopicVo) {
TopicVo vo = (TopicVo) obj;
return (vo.getTopicId().equals(this.getTopicId()));
}
return super.equals(obj);
}
二仁卷、對自定義對象排序
復寫 compareTo方法犬第,復寫規(guī)則如下:
1.返回 1 那么當前的值會排在 被比較者 后面。
2.返回 0 那么當前的值【不會被加入到 TreeSet 中】充包,因為當前的值【被認為 是跟現(xiàn)有的某一個值相等】遥椿。
3.返回 -1 會被添加到 被比較者 的前邊淆储。
代碼:
@Override
public int compareTo(Object obj) {
// TODO Auto-generated method stub
TopicVo o = (TopicVo) obj;
// 按照時間進行降序排列
if (this.getAuditAt().before(o.getAuditAt())) {
return 1;
}
if (this.getAuditAt().equals(o.getAuditAt()) && this.getTopicId().equals(o.getTopicId())) {
return 0;
}
return -1;
}
這里注意返回0的情況,有可能兩條記錄有同樣的時間數(shù)據(jù)本砰,因為要加上唯一標識TopicId也相等才能說明是同一條記錄,不然有可能會丟失數(shù)據(jù)舔株。
使用時直接把自定義對象TopicVo丟進去 TreeSet<TopicVo> 里就可以實現(xiàn)自動排序和去重了还棱,這樣子程序只需要專注于按照業(yè)務規(guī)則取數(shù)據(jù)就行了