Java中常见数据结构Set之HashSet
今天来说说Java集合中的Set系列之HashSet。
Set我们众所周知的就是虑重功能, 我们平时在项目开发中也常用到这个特性的。那么Set为何能够虑重呢? 接下来我们就看下源码吧。
Set的底层实现是HashMap(这个后面讲Map时也会讲它的源码), 当我们在HashSet中添加一个新元素时, 其实这个值是存储在底层Map的key中,而众所周知,HashMap的key值是不能重复的, 所以这里就可以达到去重的目的了。
直接看下HashSet的源码:
当我们new 一个HashSet实例时, 其实底层是新创建了一个HashMap实例。 放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个PRESENT,它是一个静态的Object对象。
下面说下HashSet需要注意的地方:
我们在项目中经常会对一些DTO进行虑重, 那么我们必须要重写equals和hashCode方法,具体可参见我的另一篇文章:重写equals就必须重写hashCode的原理分析
下面拿一个我在项目中DTO虑重的实例:
/** * 新车上市相关DTO * Created by WangMeng on 2017/8/9. */ public class NewListedCarDTO { /** * id */ private long id; /** * 车系id */ private long seriesId; /** * 头条文章id */ private long teleId; /** * 车系显示名称 */ private String seriesTitle; /** * 车系标签 */ private String seriesTag; /** * 上市时间 */ private String listTime; /** * 上市状态 * 0:不可用 1:即将上市 2:已经上市 */ private int articleType; private int listYear; private int listMonth; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof NewListedCarDTO)) return false; NewListedCarDTO that = (NewListedCarDTO) o; if (seriesId != that.seriesId) return false; if (listYear != that.listYear) return false; return listMonth == that.listMonth; } @Override public int hashCode() { int result = (int) (seriesId ^ (seriesId >>> 32)); result = 31 * result + listYear; result = 31 * result + listMonth; return result; } public long getId() { return id; } public void setId(long id) { this.id = id; } public long getSeriesId() { return seriesId; } public void setSeriesId(long seriesId) { this.seriesId = seriesId; } public long getTeleId() { return teleId; } public void setTeleId(long teleId) { this.teleId = teleId; } public String getSeriesTitle() { return seriesTitle; } public void setSeriesTitle(String seriesTitle) { this.seriesTitle = seriesTitle; } public String getSeriesTag() { return seriesTag; } public void setSeriesTag(String seriesTag) { this.seriesTag = seriesTag; } public String getListTime() { return listTime; } public void setListTime(String listTime) { this.listTime = listTime; } public int getArticleType() { return articleType; } public void setArticleType(int articleType) { this.articleType = articleType; } public int getListYear() { return listYear; } public void setListYear(int listYear) { this.listYear = listYear; } public int getListMonth() { return listMonth; } public void setListMonth(int listMonth) { this.listMonth = listMonth; } }
这里要根据seriesId和listMonth这两个字段去重, 所以必须重写equals和hashCode方法。