Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?
首先将源码逐级找出来
1.HashSet<String> hs=new HashSet<String>();
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");//因为是Set集合所以不带重复元素
因为调用的是HashSet集合中的add方法,所以我们要找出来add方法
2. public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
通过add方法我们可以看出它调用了一个put方法,我们在找出来
3.public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
然后我们可以看到它里面调用了一个putVal方法,然后第一个参数还是个hash方法,那我们就把两个方法一次拿出来
4. static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//hash值和元素的hashCode()方法有关
5.final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
//如果哈希表未初始化,就对其进行初始化
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//根据对象的哈希值计算对象的存储位置,如果该位置没有元素,就存储元素
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
/*
存入的元素和以前的元素比较哈希值
如果哈希值不同就往下执行,把元素添加到集合
如果哈希值相同就调用对象的equals方法
如果返回false:就往下执行,把元素添加到集合
如果返回true:表示元素重复,不存储
*/
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
HashSet集合添加一个元素的过程:
1.调用HsahSet集合对象的hashCode()方法获取哈希值
2.根据对象的哈希值计算对象的存储位置
3.判断该位置是否已有元素存在
没有:就将该元素存储在此位置
有:遍历该位置的所有元素,并和新存入的元素比较哈希值是否相同
不相同:将元素存入该位置
相同:调用对象的equals()方法进行比较
相同:说明该元素重复,不用存储
不相同:将元素存入该位置
4.结束
Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?的更多相关文章
- [LeetCode] 219. Contains Duplicate II 包含重复元素 II
Given an array of integers and an integer k, find out whether there are two distinct indices i and j ...
- [LeetCode] 220. Contains Duplicate III 包含重复元素 III
Given an array of integers, find out whether there are two distinct indices i and j in the array suc ...
- [LeetCode] 217. Contains Duplicate 包含重复元素
Given an array of integers, find if the array contains any duplicates. Your function should return t ...
- 从n个元素中选择k个的所有组合(包含重复元素)
LeetCode:Combinations这篇博客中给出了不包含重复元素求组合的5种解法.我们在这些解法的基础上修改以支持包含重复元素的情况.对于这种情况,首先肯定要对数组排序,以下不再强调 修改算法 ...
- JS 验证数组中是否包含重复元素
验证JS中是否包含重复元素,有重复返回true:否则返回false 方案一. function isRepeat(data) { var hash = {}; for (var i in data) ...
- Java 之 HashSet 集合
一.概述 java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致). java.util.HashSet 底层的实现是一个 ...
- leetcode-两个数组交集(包含重复元素)
Python解法代码: class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: ...
- leetcode350之实现求解两数组交集(包含重复元素)
给定两个数组,编写一个函数来计算它们的交集. 说明: 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致. 我们可以不考虑输出结果的顺序 def binarySearch(nums, t ...
- Java中的集合框架
概念与作用 集合概念 现实生活中:很多事物凑在一起 数学中的集合:具有共同属性的事物的总体 java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象 在编程时,常常需要集中存放多 ...
随机推荐
- [LeetCode]4.寻找两个正序数组的中位数(Java)
原题地址: median-of-two-sorted-arrays 题目描述: 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1, ...
- shell脚本部署redis以及redis主从复制和redis-cluster集群
# 关于脚本: # 使用root用户执行此脚本,提前关闭selinux: # 执行脚本之前,hostsIP内的IP修改成自己的机器IP: # hostsIp内的IP数量如果有增加或者减少,for循环的 ...
- web开发 小方法2-字体设置
font-size 字体大小 直接给 (任意px) 就可以 font-family:"微软雅黑"; 这个里面可以给多个用空格区分 按照先后优先级使用 当没有第一个字体的时候会 ...
- [数据生成器]UVA10054 The Necklace
应吴老师之邀,写了个数据生成器. 目前这个数据生成器可以保证生成的数据都是合法的,且效率也还不错.只是在建立普通连通图的时候zyy偷懒了,直接把所有点串起来从而保证图的连通.如果有大神有更好的方法请不 ...
- [旧][Android] ButterKnife 浅析
备注 原发表于2016.05.08,资料已过时,仅作备份,谨慎参考 前言 自上星期写 Retrofit 写吐之后 ... 我问大队长能不能换个其他什么东西写,大队长就说了个单词 ButterKnife ...
- 巧用 CSS 实现炫彩三角边框动画
最近有个小伙伴问我,在某个网站看到一个使用 SVG 实现的炫彩三角边框动画,问能否使用 CSS 实现: 很有意思的一个动画效果,立马让我想起了我在 CSS 奇思妙想边框动画 一文中介绍的边框动画,非常 ...
- linux下确认裸盘是否使用-渐入佳境
--作者:飞翔的小胖猪 --创建时间:2021年3月9日 6.1 概述 在私有云和虚拟化环境中业务方经常会根据自己的业务情况申请磁盘用作数据存储用.如果申请了磁盘但没有使用的情况,将极大的造成资源的浪 ...
- python字符串格式化输出 %和format举例
#!/usr/bin/env python # -*- coding: UTF-8 -*- #pyversion:python3.5 #owner:fuzj s1 = "i am %s, i ...
- Linux CentOS 7.X-关机、重启命令
一.命令操作 1.退出命令 退出登陆命令:logout: 2.关闭命令 立即关机:shutdown -h now(root用户) halt poweroff 延时关机:shutdown -h m ...
- Linux下安装mysql你又踩过多少坑【宇宙最全教程】
一.检查以前是否安装过MySql 因为cnetos7一般默认安装mariadb,所以要检查mysql或者mariadb是否安装 rpm -pa | grep -i mysql rpm -pa | gr ...