当前位置: 首页 > news >正文

HashSet源码分析

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

#HashSet

#####前言: 先说说HashSet的继承关系,HashSet继承了AbstractSet抽象类并实现了Set接口,AbstractSet的子类还包括TreeSet,里面实现了两个类公共的一部分方法,后面也会略有介绍。
那么HashSet到底一个怎么样的存在呢?HashSet顾名思义就是通过Hash表的方式存储数据,既然提到hash,那么肯定少不了HashMap,其实HashSet很聪明,他只需在内部维护了一个HashMap实例,将数据存储在了map中,并且集合元素不能重复。因此HashSet可以说是集合类中实现最简单的一个,他基本就是实现了List接口中定义的几个方法。
那么我想说HashSet和HashMap有什么区别呢?
1.HashMap提供键值对的方式存储数据,而HashSet仅仅提供数据存储,并没有键值对应。他获取元素的方式也只能通过遍历的方式逐个获取
2.HashMap在存入数据的时候是更加key值的hash值判断,而HashSet需要重写hashCode和equals两个方法,如果不重写则会调用默认的实现,用户在使用HashSet的时候要特别注意元素的euqals判断,有必要的话要重写一个,以免出现问题。

#####一、HashSet创建 HashSet的创建其实就是实例化一个HashMap,可以创建默认大小的HashMap实例,也可以指定initialCapacity和loadFactor,这两个参数的具体含义会在介绍HashMap的文章中讲解。

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中添加元素 HashMap中真正存放元素的地方就是HashMap,但是HashMap是K-V的形式,而HashSet中没有Key,那么他们是如何将HashSet中的元素映射到HashMap中的呢?原来作者将HashSet中的元素存放到了map的key中,而value则存放一个无意义的Object对象。这么做的好处还可以保证HashSet中的value值唯一。了解HashMap的同学知道,HashMap中校验key值唯一性的方式是通过hash值,然后根据hash值定位数组中的位置,但是也存在hash冲突的情况,那么解决hash冲突的方式就是在原来数组的位置增加一个链表,将hash值冲突,但是key值不同的元素存放在链表中。那么在判断key值是否相同的时候就用到了equals方法。从上面的描述中可以抓出几个关键点,第一hash值,第二equals方法。这就是为什么我们需要将存入HashSet的元素重写hashCode和euqals方法的根本原因。

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

#####三、HashSet遍历 我找了HashSet的源码中找了一通,然并没有找到get方法,那么我们将如何获取元素呢?我发现了iterator接口,这个接口返回的Iterator并不是HashSet自己维护的Iterator,而是通过返回HashMap的keySet().Iterator,这个迭代器遍历的是HashMap的key值。也就是HashSet中保存的value。

public Iterator<E> iterator() {
    return map.keySet().iterator();
}

转载于:https://my.oschina.net/wangen2009/blog/1536137

相关文章:

  • TCP是如何保证包的顺序传输
  • .Net Remoting常用部署结构
  • 阿里巴巴王坚:数据的价值在于计算
  • mysql 删除单表内多个字段重复的数据
  • linux中分区挂载的解释
  • ubuntu下好用的音乐播放器audacious
  • pip install read time-out
  • 固定资产分类(仅供参考 2005年),
  • 字符串操作练习:星座、凯撒密码、99乘法表、词频统计预处理
  • activiti与spring集成
  • CSS 之怀疑自己的审美 2 (Day50)
  • 哥特式建筑安全系统
  • 未能找到文件“\bin\roslyn\csc.exe”
  • 「hadoop」log4j参考
  • TensorFlow Serving 1.0的技术细节在Google I/O大会上公布
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 2017-08-04 前端日报
  • vue的全局变量和全局拦截请求器
  • 编写高质量JavaScript代码之并发
  • 产品三维模型在线预览
  • 工作中总结前端开发流程--vue项目
  • 猴子数据域名防封接口降低小说被封的风险
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 前端面试总结(at, md)
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 事件委托的小应用
  • 一起参Ember.js讨论、问答社区。
  • 最简单的无缝轮播
  • # Java NIO(一)FileChannel
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)h264中avc和flv数据的解析
  • (转)linux下的时间函数使用
  • (转)visual stdio 书签功能介绍
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net 按比例显示图片的缩略图
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET 依赖注入和配置系统
  • .NET委托:一个关于C#的睡前故事
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • /bin/rm: 参数列表过长"的解决办法
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [Android] Android ActivityManager
  • [BUUCTF]-PWN:[极客大挑战 2019]Not Bad解析
  • [CF407E]k-d-sequence
  • [C语言]编译和链接