java集合-HashSet源码解析
2024-08-29 21:48:13
HashSet 无序集合类
- 实现了Set接口
- 内部通过HashMap实现
// HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
//重要:HashMap HashSet就是通过HashMap保存数据, HashSet的值就是HashMap的key
private transient HashMap<E,Object> map; // 使用transient修饰不会被序列化
//HashMap 为<key, value>的键值对, 既然HashSet的值就是HashMap的key, 那么HashMap的值呢,当然就是这个PRESENT,HashMap所有的value都是同一个对象
private static final Object PRESENT = new Object();
// 默认构造函数,创建一个HashMap对象
public HashSet() {
map = new HashMap<>();
}
//将一个已知的collection转换为HashSet
public HashSet(Collection<? extends E> c) {
//Collection<? extends E> c 限制了类型上限为E,也就是c只能是E类型或E的子类,防止参数是非Set类型
//如果没有指定HashMap的capacity, 那么默认的就是16
//根据 threshold = capacity * loadFactor, 可以计算出 capacity
//Math.max((int) (c.size()/.75f) + 1, 16) 这个意思就是capacity如果没超过16, 那么就直接使用默认的16
// 容量设置为4/3倍
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
//将已知的collection转换为HashSet的方法
//addAll方法是HashSet的父类AbstractCollection的方法,为了便于阅读,会将代码粘贴在下面
addAll(c);
}
// 带有初始容量和因子的构造函数
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
//addAll方法是HashSet的父类AbstractCollection的方法
public boolean addAll(Collection<? extends E> c) {
boolean modified = false; // 只要添加了元素就返回true
for (E e : c)
//此处的add方法由HashSet重写实现
if (add(e))
modified = true;
return modified;
}
//HashSet的核心方法来了, 没错,就这么简单
public boolean add(E e) {
//应证了上面所说的key为HashSet的值
return map.put(e, PRESENT)==null;
}
//剩下这些方法都是跟Map相关的了,只要熟悉了HashMap, 那就太简单了,就不说了
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
public void clear() {
map.clear();
}
}
补充
泛型
泛型的上限通配符<? extends T>
<? extends T>是 Upper Bound(上限) 的通配符,用来限制元素的类型的上限,比如
List<? extends Fruit> fruits;
表示集合中的元素类型上限为Fruit类型,即只能是Fruit或者Fruit的子类。
泛型的下限通配符<? super T>
<? super E> 是 Lower Bound(下限) 的通配符 ,用来限制元素的类型下限,比如
List<? super Apple> apples;
表示集合中元素类型下限为Apple类型,即只能是Apple或Apple的父类。
参考
- HashSet其实就那么一回事儿之源码浅析 https://www.cnblogs.com/dongying/p/4024519.html
- Java泛型中<? extends E>和<? super E>的区别 https://www.cnblogs.com/xiarongjin/p/8309755.html
最新文章
- ViewStub的简单解析和使用场景
- JavaScript--DOM事件(笔记)
- java 常量池
- Python的安装和详细配置(转)
- 基于GeoHash算法的附近点搜索实现(一)
- Step one : 熟悉Unix/Linux Shell 常见命令行 (二)
- POJ2185(KMP)
- SQL随记(三)
- 【宝塔linux】 导入mysql 大文件失败的问题
- Java中的Dom4j
- 1-VScode格式化ESlint-方法(最全最好用方法!)
- Spark记录-阿里巴巴开源工具DataX数据同步工具使用
- 当我的url请求会变成jsp页面路径时的解决办法
- secFox setting
- SpringMVC源码学习之request处理流程
- C# Liseview的使用方法之一:滚动到选中的行
- 树莓派实践部分——P2P文件下载机torrent之Raspberry Pi管理
- 湖南大学ACM程序设计新生杯大赛(同步赛)E - Permutation
- 线程协作-CountDownLatch
- WebSocket --为什么引入WebSocket协议
热门文章
- Servlet不再是烦恼
- Windows10系统:任务栏中电池图标消失问题的解决方法
- 利用 vue-cli 构建一个 Vue 项目
- ASP.NET Core Middleware 抽丝剥茧
- Python爬虫入门教程 41-100 Fiddler+夜神模拟器+雷电模拟器配置手机APP爬虫部分
- ES 09 - 定制Elasticsearch的分词器 (自定义分词策略)
- Angular动态创建组件之Portals
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)
- Docker最全教程——数据库容器化(十)
- Python两步实现关联规则Apriori算法,参考机器学习实战,包括频繁项集的构建以及关联规则的挖掘