我们都知道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 (三)相关推荐

  1. 容器源码分析之LinkedList(三)

    LinkedList的构造方法 public class LinkedList<E>extends AbstractSequentialList<E>implements Li ...

  2. 容器源码分析之TreeSet(五)

    HashSet是借助于HashMap的key不允许重复这个特性来实现的.HashMap是操作键值对,而HashSet是操作HashMap的key完成相关操作,TreeSet比HashSet加了排序的功 ...

  3. Spring IOC 容器源码分析

    Spring IOC 容器源码分析 创建时间: 2017-11-15 00:00:00 [TOC] Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring ...

  4. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  5. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  6. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  7. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  8. Spring IOC 容器源码分析系列文章导读

    1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...

  9. Spring IOC 容器源码分析 - 余下的初始化工作

    1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...

最新文章

  1. Java单向链表操作详解
  2. java并发性是指什么_java – 什么是“非阻塞”并发,它与普通并发性有什么不同?...
  3. python查找字符串关键词_Python字符串查找基本操作案例解析
  4. Openstack介绍
  5. 三维重建15:最近遇到的-标定-EKF-优化方法等
  6. 数据中心扩张和产能计划
  7. hadoop 单节点安装
  8. golang byte转string_golang版memcached之groupcache缓存入门
  9. python 删除指定时间之前文件的脚本 包括下级目录
  10. c语言 指针_C语言野指针以及非法内存操作
  11. LeetCode 144 ——二叉树的前序遍历
  12. ESP32-CAM模块网络摄像头demo加装舵机控制教程
  13. Nessus部署及简单使用
  14. python怎么解压rar文件
  15. Android AR ---HelloAR(用的EasyAR 免费版)
  16. 小程序 php cookie,微信小程序模拟 cookie
  17. 逆时针旋转坐标系的转换
  18. 目前宽带的接入方式有哪些
  19. JS实现网站声音提示,兼容IE与chrome,附谷歌chrome浏览器无法自动播放声音解决方法
  20. 华为为何取名鸿蒙系统,华为自主操作系统为何取名鸿蒙,看完西游记才知道霸气在哪里?...

热门文章

  1. “白加黑”远控木马技术分析及手杀方案
  2. Python 让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序
  3. 回腾讯了......
  4. 总结了24个C++的大坑,看你能躲过几个?
  5. GitHub:再见,master!
  6. Kafka参数图鉴——unclean.leader.election.enable
  7. Django视图(二)
  8. 如何给小白解释什么是编解码器
  9. 专访快手传输算法负责人周超博士:LAS标准的推出离不开信念感
  10. HTTP over QUIC重命名为“HTTP / 3”协议