java中使用HashSet去重必須重寫hashCode()和equals()叛溢。
但是HashSet去重并不會(huì)把原來的給覆蓋掉,而是直接丟棄新的。
例如有一個(gè)類:
public class BaseEntity implements Serializable {
private String id;
private String name;
// ...... 演示不寫get set toString 方法和構(gòu)造器
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BaseEntity)) return false;
BaseEntity that = (BaseEntity) o;
return Objects.equals(getId(), that.getId());
}
@Override
public int hashCode() {
return Objects.hash(getId());
}
}
在寫一個(gè)main方法:
public static void main(String[] args) {
Set<BaseEntity> baseEntitySet = new HashSet<>();
BaseEntity baseEntity1 = new BaseEntity("id=1", "張三");
BaseEntity baseEntity2 = new BaseEntity("id=2", "李四");
BaseEntity baseEntity3 = new BaseEntity("id=1", "王五");
baseEntitySet.add(baseEntity1);
baseEntitySet.add(baseEntity2);
baseEntitySet.add(baseEntity3);
for(BaseEntity item : baseEntitySet){
System.out.println(item);
}
}
然后會(huì)得到如下結(jié)果:
BaseEntity{id='id=2', name='李四'}
BaseEntity{id='id=1', name='張三'}
我們就會(huì)發(fā)現(xiàn)name="王五"的對(duì)象并沒有覆蓋name="張三"的對(duì)象。
原因是因?yàn)镠ashSet底層使用的是HashMap词疼。
當(dāng)調(diào)用add()時(shí),會(huì)把對(duì)象存入key中帘腹,value則為一個(gè)靜態(tài)的Object對(duì)象。
源碼如下:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
但是HasHMap遇到重復(fù)的key時(shí)只會(huì)把value替換掉许饿。
而HashSet存進(jìn)去的對(duì)象是放在HashMap中的key里阳欲。
所以使用HasHSet去重得到的是第一個(gè)未重復(fù)對(duì)象,后續(xù)重復(fù)的對(duì)象直接被丟棄陋率。沒有被覆蓋球化。