今天来说说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. 深入浅出数据结构C语言班(11)——简要介绍算法时间复杂度

    在接下来的数据结构博文中,我们将会开始接触到一些算法,也就是"解决某个问题的方法",而解决同一个问题总是会存在不同的算法,所以我们需要在不同的算法之中做出抉择,而做出抉择的根据往往 ...

  2. 9. leetcode 389. Find the Difference

    Given two strings s and t which consist of only lowercase letters. String t is generated by random s ...

  3. How Django works?

    Django是如何工作的? 概念 以线上版本中Django和Nginx.uwsgi搭配,这里首先要了解uWSGI.uwsgi.WSGI分别代表着什么,其中uWSGI实现了uwsgi.WSGI.HTTP ...

  4. 如何在Linux上使用VIM进行.Net Core开发

    对于在Linux上开发.Net Core的程序员来说, 似乎都缺少一个好的IDE. Windows上有Visual Studio, Mac上有Visual Studio for Mac, 难道Linu ...

  5. 01迷宫 洛谷 p1141

    题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...

  6. 一步一步学J2SE-HashMap的实现原理

    HashMap数据结构图 HashMap的数据结构是通过数组加链表实现的.数组是HashMap的主体,链表是为了解决Hash碰撞问题. HashMap的Get方法 1.  在get的时候首先判断key ...

  7. 【转】DHCP协议详解

    协议分析 - DHCP协议解码详解 DHCP协议简介 DHCP,全称是 Dynamic Host Configuration Protocol﹐中文名为动态主机配置协议,它的前身是 BOOTP,它工作 ...

  8. Git的commit your changes or stash them before you can merge

    今天用git pull来更新代码,遇到了下面的问题: error: Your local changes to the following files would be overwritten by ...

  9. 秒懂OAuth2.0

    1.引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式:授权码模式 非常简单的一件事情,网上一堆神乎其神的讲解,让我不得不写一篇文章来终结它们. 一项新的技术,无非就是了解它是什么,为什 ...

  10. Python下的OpenCV学习 01 —— 在Linux下安装OpenCV

    一.OpenCV简要介绍 OpenCV是一个跨平台的计算机视觉库,可以运行在Windows.Linux.MacOS等操作系统上.OpenCV提供了众多语言的接口,其中就包含了Python,Python ...