Java面试题 从源码角度分析HashSet实现原理?
面试官:请问HashSet有哪些特点?
应聘者:HashSet实现自set接口,set集合中元素无序且不能重复;
面试官:那么HashSet 如何保证元素不重复?
应聘者:因为HashSet底层是基于HashMap实现的,当你new一个HashSet时候,实际上是new了一个map,执行add方法时,实际上调用map的put方法,value始终是PRESENT,所以根据HashMap的一个特性: 将一个key-value对放入HashMap中时,首先根据key的hashCode()返回值决定该Entry的存储位置,如果两个key的hash值相同,那么它们的存储位置相同。如果这个两个key的equalus比较返回true。那么新添加的Entry的value会覆盖原来的Entry的value,key不会覆盖。因此,如果向HashSet中添加一个已经存在的元素,新添加的集合元素不会覆盖原来已有的集合元素;
源码分析
先来看一下无参的构造函数:
public HashSet() {
map = new HashMap<>();
}
很显然,当你new一个HashSet的时候,实际上是new了一个HashMap
再来看一下add方法:
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
定义一个虚拟的Object PRESENT是向map中插入key-value对应的value,因为HashSet中只需要用到key,而HashMap是key-value键值对;所以,向map中添加键值对时,键值对的值固定是PRESENT。
源码中HashSet的绝大部分方法都是通过调用HashMap的方法来实现的,其他的方法,就请大家自己查阅一下源码吧。
Java面试题 从源码角度分析HashSet实现原理?的更多相关文章
- 从源码角度分析 MyBatis 工作原理
一.MyBatis 完整示例 这里,我将以一个入门级的示例来演示 MyBatis 是如何工作的. 注:本文后面章节中的原理.源码部分也将基于这个示例来进行讲解.完整示例源码地址 1.1. 数据库准备 ...
- 源码角度分析-newFixedThreadPool线程池导致的内存飙升问题
前言 使用无界队列的线程池会导致内存飙升吗?面试官经常会问这个问题,本文将基于源码,去分析newFixedThreadPool线程池导致的内存飙升问题,希望能加深大家的理解. (想自学习编程的小伙伴请 ...
- JAVA面试题 StringBuffer和StringBuilder的区别,从源码角度分析?
面试官Q1:请问StringBuffer和StringBuilder有什么区别? 这是一个老生常谈的话题,笔者前几年每次面试都会被问到,作为基础面试题,被问到的概率百分之八九十.下面我们从面试需要答到 ...
- Java集合之HashMap源码实现分析
1.简介 通过上面的一篇随笔我们知道了HashSet的底层是采用Map实现的,那么Map是什么?它的底层又是如何实现的呢?这下我们来分析下源码,看看具体的结构与实现.Map 集合类用于存储元素对(称作 ...
- 【原创】源码角度分析Android的消息机制系列(三)——ThreadLocal的工作原理
ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Android源码(API24)中对ThreadLocal的定义: public class ThreadLocal<T> 即 ...
- 从源码角度分析 Kotlin by lazy 的实现
by lazy 的作用 延迟属性(lazy properties) 是 Kotlin 标准库中的标准委托之一,可以通过 by lazy 来实现. 其中,lazy() 是一个函数,可以接受一个 Lamb ...
- java并发系列(四)-----源码角度彻底理解ReentrantLock(重入锁)
1.前言 ReentrantLock可以有公平锁和非公平锁的不同实现,只要在构造它的时候传入不同的布尔值,继续跟进下源码我们就能发现,关键在于实例化内部变量sync的方式不同,如下所示: /** * ...
- Android的Message Pool是什么——源码角度分析
原文地址: http://blog.csdn.net/xplee0576/article/details/46875555 Android中,我们在线程之间通信传递通常采用Android的消息机制,而 ...
- 【原创】源码角度分析Android的消息机制系列(五)——Looper的工作原理
ι 版权声明:本文为博主原创文章,未经博主允许不得转载. Looper在Android的消息机制中就是用来进行消息循环的.它会不停地循环,去MessageQueue中查看是否有新消息,如果有消息就立刻 ...
随机推荐
- 用C实现OOP面向对象编程(1)
如摘要所说,C语言不支持OOP(面向对象的编程).并这不意味着我们就不能对C进行面向对象的开发,只是过程要复杂许多.原来以C++的许多工作,在C语言中需我们手动去完成. 博主将与大家一起研究一下如下用 ...
- uniConnection断线重联(tag属性颇有深意,这样就可以在某些情况下,不用继承实现新控件就可以达到自己的目的)
群友无法呼吸提供的,谢谢他了. http://blog.sina.com.cn/s/blog_44fa172f0102wb7h.html
- inno setup 配合istools
istool,可以认为是inno setup的IDE吧 用用就知道了,istool用起来方便些,当然,脚本写好了,用不用istool就无所谓了
- ZooKeeper学习第七期--ZooKeeper一致性原理(转)
转载来源:https://www.cnblogs.com/sunddenly/p/4138580.html 一.ZooKeeper 的实现 1.1 ZooKeeper处理单点故障 我们知道可以通过Zo ...
- 作为服务注册中心,Eureka比Zookeeper好在哪里
CAP是Consistency.Availablity和Partition Tolerance的缩写.一般的分布式系统最多满足其中两条.而Partition Tolerance是分布式系统的关键,因此 ...
- Powerdesigner 从Oracle到mssql2008
database->update model for database> ->系统数据源->选择用户,选择表,确定... 1.database->change Curre ...
- 宜信开源|手把手教你安装第一个LAIN应用
LAIN是宜信公司大数据创新中心开发的开源PaaS平台.在金融的场景下,LAIN 是为解放各个团队和业务线的生产力而设计的一个云平台.LAIN 为宜信大数据创新中心各个团队提供了统一的测试和生产环境, ...
- Centos7 fstab盘符挂载硬盘导致重启系统失败解决办法
服务器拥有多个硬盘插槽,在进行维护或重启时,这些硬盘的相对位置可能发生变化.利用盘符(dev/vda)方式挂载磁盘,可能由于磁盘顺序变化导致重启时读取fstab文件发生错误,从而无法正常重启服务器. ...
- 使用BurpSuite的Collaborator查找.Onion隐藏服务的真实IP地址
本文转载!!! 原文地址:http://www.4hou.com/technology/10367.html 翻译来自:http://digitalforensicstips.com/2017/11/ ...
- 最全java多线程总结2--如何进行线程同步
上篇对线程的一些基础知识做了总结,本篇来对多线程编程中最重要,也是最麻烦的一个部分--同步,来做个总结. 创建线程并不难,难的是如何让多个线程能够良好的协作运行,大部分需要多线程处理的事情都不 ...