Java中常见数据结构Set之HashSet

时间:2022-05-16
本文章向大家介绍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方法。