文章同步更新在个人博客:HashSet怎样保证元素不重复

都知道HashSet中不能存放重复元素,有时候可以用来做去重操作等。但是其内部是怎么保证元素不重复的呢?下面从源码去看看。

打开HashSet源码,发现其内部维护了一个HashMap:

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object(); /**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
...
}

HashSet的构造方法其实就是在内部实例化了一个HashMap对象。其中还会看到一个static final的PRESENT变量,这个稍候再说,其实没什么实际用处。

想知道为什么HashSet不能存放重复对象,那么第一步当然是看它的add方法怎么进行的判重,代码如下:

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

。。。好吧,就把元素存放在了map里面。但是值得注意的是元素值作为的是map的key,map的value则是前面提到的PRESENT变量,这个变量只作为放入map时的一个占位符而存在,所以没什么实际用处。

其实,这时候答案已经出来了:HashMap的key是不能重复的,而这里HashSet的元素又是作为了map的key,当然也不能重复了

HashSet怎么做到保证元素不重复的原因找到了,文章也就结束了。。。等等,顺便看一下HashMap里面又是怎么保证key不重复的吧,代码如下:

public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;
addEntry(hash, key, value, i);
return null;
}

其中最关键的一句:

if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

调用了对象的hashCode和equals方法进行的判断,所以又得出一个结论:若要将对象存放到HashSet中并保证对象不重复,应根据实际情况将对象的hashCode方法和equals方法进行重写

HashSet怎样保证元素不重复的更多相关文章

  1. 面试官:HashSet如何保证元素不重复?

    本文已收录<Java常见面试题>系列,Git 开源地址:https://gitee.com/mydb/interview HashSet 实现了 Set 接口,由哈希表(实际是 HashM ...

  2. HashSet 如何保证元素不重复——hash码

    HashSet 不重复主要add 方法实现,使用 add 方法找到是否存在元素,存在就不添加,不存在就添加.HashSet 主要是基于HashMap 实现的,HashMap 的key就是 HashSe ...

  3. HashSet集合存储数据的结构和HashSet集合存储元素不重复的原理

    HashSet集合存储数据的结构 HashSet集合存储元素不重复的原理 //创建HashSet集合对象 Hashset<String> set = new HashSet<> ...

  4. 利用 HashSet 去过滤元素是否重复

    HashSet<Integer> hashSet = new HashSet<Integer>(); for (int i = resultDoctorDetails.size ...

  5. 集合框架(HashSet存储自定义对象保证元素唯一性)

    HashSet如何保证元素唯一性的原理 1.HashSet原理 a. 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降 ...

  6. 面试题: hashset如何保证值不会被重复的

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 众所周知,HashSet 的值是不可能被重复的,在业务上经常被用来做数据去重的操作,那么,其内部究竟是怎 ...

  7. HashSet 添加/遍历元素源码分析

    HashSet 类图 HashSet 简单说明 HashSet 实现了 Set 接口 HashSet 底层实际上是由 HashMap 实现的 public HashSet() { map = new ...

  8. HashSet中是如何判断元素是否重复的

    HashSet不能添加重复的元素,当调用add(Object)方法时候, 首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素: 如果已存在则调用Obje ...

  9. HashSet保证元素唯一原理以及HashMap扩容机制

    一.HashSet保证元素唯一原理: 依赖于hashCode()和equals()方法1.唯一原理: 1.1 当HashSet集合要存储元素的时候,会调用该元素的hashCode()方法计算哈希值 1 ...

随机推荐

  1. (3)Linux命令分类汇总(7~12)

    Linux命令分类汇总(7~12) (七)用户管理命令(12个) 1    useradd cdgs   添加用户. 2     usermod 修改系统已经存在的用户属性. 3    userdel ...

  2. 【DSP开发】硬件信号量在多核处理器核间通信中的应用

    硬件信号量在多核处理器核间通信中的应用 刘德保1,汪安民1,韩道文2 1.同方电子科技有限公司研究所,九江 332009:2.解放军电子工程学院 摘要: 在多核处理器的软件设计中,核间通信机制是关键所 ...

  3. 关于Angular+ngx-perfect-scrollbar自定义各大浏览器滚动条样式的解决方法

    资料: http://manos.malihu.gr/jquery-custom-content-scroller/  (此项是结合Jquery使用的,在此并未采用) https://www.npmj ...

  4. POJ 3229:The Best Travel Design

    Description Dou Nai ), and the end of the travel route hours on traveling every day. Input There are ...

  5. 牛客小白月赛16 H 小阳的贝壳 (差分+线段树)

    链接:https://ac.nowcoder.com/acm/contest/949/H来源:牛客网 题目描述 小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 colico ...

  6. kafka2.10集群搭建(一)

    一.kafka集群搭建 1.上传解压 2.配置文件的配置 1.修改 server.properties文件 broker.id=11 #192.168.199.11 #21 一般使用ip后三位 lis ...

  7. DecodingGenome(CodeForces-222E)【矩阵快速幂】

    题目链接:https://vjudge.net/contest/333591#problem/L 题意:用m个字符构成长度为n的串,其中存在形如“ab”(表示a后不能放置b)的条件约束,问共有多少种构 ...

  8. Django-djangorestframework-渲染模块

    目录 渲染模块 渲染模块的效果 源码分析 如何自定义配置使用渲染类 自定义渲染模块 渲染模块 可以根据用户请求 URL 或 用户可接受的类型,筛选出合适的 渲染组件. reponse 数据 json ...

  9. shell习题第15题:看数字找规律

    [题目要求] 请仔细查看如下几个数字的规律,并使用shell脚本输出后面的十个数字 10 31 53 77 105 141... ... [核心要点] 计算两个数值之间的差值 [脚本] #!/bin/ ...

  10. GoLang语言环境搭建及idea集成开发(超详细)

    一.所需安装包(windows) 1. https://golang.org/dl/  下载 MSI installer.不会翻墙的自己找国内下载,双击运行,按照提示安装即可.环境变量自动配置 2.i ...