今天来说说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方法。

Java中常见数据结构Set之HashSet的更多相关文章

  1. Java中常见数据结构List之ArrayList

    这里主要包含ArrayList和LinkedList, 然后再添加一个:CopyOnWriteArrayList 关于Java中的集合内容, 感觉都已经被写烂了, 我这里主要是做个复习, 再从扒下源代 ...

  2. Java中常见数据结构:list与map -底层如何实现

    1:集合 2 Collection(单列集合) 3 List(有序,可重复) 4 ArrayList 5 底层数据结构是数组,查询快,增删慢 6 线程不安全,效率高 7 Vector 8 底层数据结构 ...

  3. Java中常见数据结构:list与map

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  4. Java中常见数据结构Map之LinkedHashMap

    前面已经说完了HashMap, 接着来说下LinkedHashMap. 看到Linked就知道它是有序的Map,即插入顺序和取出顺序是一致的, 究竟是怎样做到的呢? 下面就一窥源码吧. 1, Link ...

  5. Java中常见数据结构Map之HashMap

    之前很早就在博客中写过HashMap的一些东西: 彻底搞懂HashMap,HashTableConcurrentHashMap关联: http://www.cnblogs.com/wang-meng/ ...

  6. Java中常见数据结构List之LinkedList

    二,LinkedList 1, linkedList底层数据结构 linkedList底层是一个双向链表 2,LinkedList和ArrayList的对比 1.顺序插入速度ArrayList会比较快 ...

  7. Java中常见数据结构

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  8. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  9. java中的数据结构(集合|容器)

    对java中的数据结构做一个小小的个人总结,虽然还没有到研究透彻jdk源码的地步.首先.java中为何需要集合的出现?什么需求导致.我想对于面向对象来说,对象适用于描述任何事物,所以为了方便对于对象的 ...

随机推荐

  1. [硬件]_ELVE_VS2015下opencv3.3的配置问题

    0x00  引言 最近想搞一下摄像头,但是我的Windows版本是64位的,opencv3.3貌似也只支持64位系统了,所以就配置一下win10+vs2015+opencv3.3的环境变量,具体下载和 ...

  2. EXchange导出通讯录提取url纯文本

    用outlook链接邮箱 文件-打开和导出--导出到文件--逗号分隔值--选择联系人--保存 保存为一个后缀为csv的文件 打开该文件  选中该列 用替换功能删掉()符号 用vba脚本删掉汉字 Sub ...

  3. [PGM] Exact Inference for calculating marginal distribution

    如何在贝叶斯网络中求解某变量的边缘分布? 这是一个问题. 贝叶斯网络如下: CPTs如下: (1) How to compute p( L | C = high )? p( L | C = high  ...

  4. java中string.trim()函数的使用

    java中string.trim()函数的的作用是去掉字符串开头和结尾的空格,防止不必要的空格导致的错误. public static void main(String arg[]){ String ...

  5. 605. Can Place Flowers种花问题【leetcode】

    Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...

  6. html5 mdn一些精彩的案例

    https://developer.mozilla.org/zh_CN/docs/Games/Examples

  7. jmeter - 断言

    jmeter中有个元件叫做断言(Assertion),它的作用和loadrunner中的检查点类似: 用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致. 使用断言 ...

  8. Entity Framework Core 2.0 新特性

    本文翻译来自:https://docs.microsoft.com/en-us/ef/core/what-is-new/index 一.模型级查询过滤器(Model-level query filte ...

  9. Spring集成RabbitMQ-使用RabbitMQ更方便

    如果提到Spring,你脑海中对他的印象还停留在SSH三大框架之一,那或许你该好好重新认识这个家伙. 在IT技术日新月异的今天,他还能让你忘不了并与他朝夕相处,他,肯定有自己的绝活.如今他早已经不是孤 ...

  10. QTextEdit控件使用

    QTextEdit控件使用 QTextEdit *mpContentTextEdit = new QTextEdit(this); //设置占位符文本 mpContentTextEdit->se ...