容器源码分析之HashSet (三)
我们都知道HashSet集合是不允许重复元素的,因此这个类的利用什么来保证这个集合里面不会有重复的元素呢?
结论是:HashSet是借助于HashMap的key不允许重复这个特性来实现的。HashMap是操作键值对,而HashSet是操作HashMap的key完成相关操作,或者说,HashSet全部的操作是借助于HashMap经过某种封装得到的。
1.HashSet的继承结构
public class HashSet<E>extends AbstractSet<E>implements Set<E>, Cloneable, java.io.Serializable
HashSet继承了AbstractSet抽象类,也实现了Set、Cloneable和Serializable接口。
2.HashMap的属性
private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();
HashSet仅仅有两个成员,我们知道HashSet是操作HashMap的key的,还知道HashMap的value不能放null,所以成员PRESENT
是用来塞HashMap的value的。
3. HashSet的构造函数
public HashSet() {map = new HashMap<>();}public HashSet(Collection<? extends E> c) {map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));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);}
这里初始化HashSet其实就是HashMap,而且从HashSet(Collection
public boolean add(E e) {return map.put(e, PRESENT)==null;}
第一次看这个函数有点小别扭,仔细想想才想通,HashMap的put方法是找不到相同的key,操作成功才等于null,找到相同的值返回旧值。
其他方法也很简单,都是调用HashMap的api
public Iterator<E> iterator() {return map.keySet().iterator();}public int size() {return map.size();}public boolean isEmpty() {return map.isEmpty();}public boolean contains(Object o) {return map.containsKey(o);}public boolean add(E e) {return map.put(e, PRESENT)==null;}public boolean remove(Object o) {return map.remove(o)==PRESENT;}public void clear() {map.clear();}
容器源码分析之HashSet (三)相关推荐
- 容器源码分析之LinkedList(三)
LinkedList的构造方法 public class LinkedList<E>extends AbstractSequentialList<E>implements Li ...
- 容器源码分析之TreeSet(五)
HashSet是借助于HashMap的key不允许重复这个特性来实现的.HashMap是操作键值对,而HashSet是操作HashMap的key完成相关操作,TreeSet比HashSet加了排序的功 ...
- Spring IOC 容器源码分析
Spring IOC 容器源码分析 创建时间: 2017-11-15 00:00:00 [TOC] Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring ...
- Spring IOC 容器源码分析 - 填充属性到 bean 原始对象
1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...
- Spring IOC 容器源码分析 - 循环依赖的解决办法
1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...
- Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
- Spring IOC 容器源码分析系列文章导读
1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...
- Spring IOC 容器源码分析 - 余下的初始化工作
1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...
最新文章
- Java单向链表操作详解
- java并发性是指什么_java – 什么是“非阻塞”并发,它与普通并发性有什么不同?...
- python查找字符串关键词_Python字符串查找基本操作案例解析
- Openstack介绍
- 三维重建15:最近遇到的-标定-EKF-优化方法等
- 数据中心扩张和产能计划
- hadoop 单节点安装
- golang byte转string_golang版memcached之groupcache缓存入门
- python 删除指定时间之前文件的脚本 包括下级目录
- c语言 指针_C语言野指针以及非法内存操作
- LeetCode 144 ——二叉树的前序遍历
- ESP32-CAM模块网络摄像头demo加装舵机控制教程
- Nessus部署及简单使用
- python怎么解压rar文件
- Android AR ---HelloAR(用的EasyAR 免费版)
- 小程序 php cookie,微信小程序模拟 cookie
- 逆时针旋转坐标系的转换
- 目前宽带的接入方式有哪些
- JS实现网站声音提示,兼容IE与chrome,附谷歌chrome浏览器无法自动播放声音解决方法
- 华为为何取名鸿蒙系统,华为自主操作系统为何取名鸿蒙,看完西游记才知道霸气在哪里?...
热门文章
- “白加黑”远控木马技术分析及手杀方案
- Python 让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序
- 回腾讯了......
- 总结了24个C++的大坑,看你能躲过几个?
- GitHub:再见,master!
- Kafka参数图鉴——unclean.leader.election.enable
- Django视图(二)
- 如何给小白解释什么是编解码器
- 专访快手传输算法负责人周超博士:LAS标准的推出离不开信念感
- HTTP over QUIC重命名为“HTTP / 3”协议