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方法。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏7号代码

面向对象设计原则

面向对象设计的目标之一在于支持可维持性复用,一方面需要实现设计方案或者源代码的复用,另一方面要确保系统能够易于扩展和修改,具有较好的灵活性。

34040
来自专栏Java成神之路

Java_String_01_由转义字符串得到其原本字符串

在开发企业微信电子发票之拉取电子发票接口的时候,微信服务器会发送给我们一个2层的转义字符串,而我们要想得到我们想要的结果,就需要进行一些处理:

11530
来自专栏Golang语言社区

用Golang写一个搜索引擎

本篇较长较枯燥,请保持耐心看完。 前面两章介绍了一下倒排索引以及倒排索引字典的两种存储结构,分别是 跳跃表 和 哈希表 ,本篇我们介绍另一种数据结构,他也被大量...

48570
来自专栏数据结构与算法

洛谷P3178 [HAOI2015]树上操作

题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a 。操作 2 :把某个节...

36480
来自专栏猿人谷

(重点)链式栈

顺序栈的实现在于使用了数组这个基本数据结构,数组中的元素在内存中的存储位置是连续的,且编译器要求我们在编译期就要确定数组的大小,这样对内存的使用效率并不高,一来...

24290
来自专栏desperate633

LintCode 简化路径题目分析代码

思路比较简单,遇到..就回到上一级,遇到.或者空就不处理。 我们使用一个队列来处理,同时将三个需要特殊处理的字符存到一个set里面

7610
来自专栏数据结构与算法

cf914D. Bash and a Tough Math Puzzle(线段树)

可以这么想,如果能成功的话,我们可以把那个数改成$1$,这样比$x$大的数就不会对答案产生影响了。

10510
来自专栏mySoul

java队列

队列为特殊的线性表,队列的特点先进先出(FIFO),队列插入为入队,队列删除为出对。

31000
来自专栏battcn

一起学设计模式 - 访问者模式

访问者模式: 预留通路,回调实现。它的实现主要就是通过预先定义好调用的通路,在被访问的对象上定义 accept方法,在访问者的对象上定义 visit方法;然后在...

8210
来自专栏君赏技术博客

ClangFormat语法1.0

AllowShortIfStatementsOnASingleLine (bool)

12530

扫码关注云+社区

领取腾讯云代金券