HashSet底层HashMap源码分析
在看HashSet源码的时候,意外发现底层HashMap保存的value居然不是null,而是保存一个Object作为Value。顿觉有悖常理,于是来分析一下:
HashSet的add方法:
public boolean add(E e) {return map.put(e, PRESENT)==null;}
可以看到这里调用底层HashMap的时候,往value里放了一个PRESENT,中文直译为“存在”,为什么叫PRESENT,很形象,待会解释。
我们再来看看PRESENT是什么:
private static final Object PRESENT = new Object();
PRESENT是一个类静态变量,也就是说整个类所有的value也就这么一个对象,而且这个对象根本没有任何意义。
带着问题去分析:
- 问题一:按理说,HashSet只需要判断是否重复(存在),压根就不需要存放value的呀,那么存放一个null不就好了?何必存一个没有意义的Object?这个问题需要解释问题二
 - 问题二:为什么add方法需要返回值?返回值的意义是什么?
 - 问题三:如果给value存null会发生什么?
 
先分析问题三,如果存了一个null,我们知道HashMap是允许null值的,那么我们去看看map.put方法,存null会怎么样:
public V put(K key, V value) {
	return putVal(hash(key), key, value, false, true);
}
    /**
     * Implements Map.put and related methods.
     * @return previous value, or null if none
     */
看注释最后一行:返回这个key之前的value,如果这个key之前没有value,那么返回null。
如果我们HashSet存null进去,那么分析一下返回值:
- 如果HashSet中已有了这个key,比如Set中已经有了一个KV:("张三", null),又填进去一个KV:("张三", null),此时应当返回privous value,也就是null
 - 如果HashSet中没有这个key,比如第一次添加KV:("张三", null),那么应当返回null
 
发现问题了,如果HashSet中把null存为value,那么无论set中是否已有重复,add方法都会返回null,那么add方法就无法检验是否重复。
问题二也顺带解决了,add方法返回值,就是判断HashMap.put方法返回是否为null,也就是判断add方法添加的新元素是否已经重复。
问题一也解决了,这个Object本身确实没有意义,但是它对我们Set有意义:
它唯一的意义就是,它不等于null呀。。。也就是说,只要你开心,你往里放个什么东西都行。(毕竟还是要考虑内存占用的)
现在你肯定知道为什么这个Object叫“存在”了吧?因为张麻子说过,你和钱对我都不重要,有你,对我很重要。
HashSet底层HashMap源码分析的更多相关文章
- jdk7 HashSet和HashMap源码分析
		
先来看看HashMap的一些成员变量以及他们的含义 /** * The default initial capacity - MUST be a power of two. */ static fin ...
 - Java HashMap源码分析(含散列表、红黑树、扰动函数等重点问题分析)
		
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
 - Java中HashMap源码分析
		
一.HashMap概述 HashMap基于哈希表的Map接口的实现.此实现提供所有可选的映射操作,并允许使用null值和null键.(除了不同步和允许使用null之外,HashMap类与Hashtab ...
 - HashMap源码分析和应用实例的介绍
		
1.HashMap介绍 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射.HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.S ...
 - Java HashSet和HashMap源码剖析
		
转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...
 - Java源码解析——集合框架(五)——HashMap源码分析
		
HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...
 - 源码分析系列1:HashMap源码分析(基于JDK1.8)
		
1.HashMap的底层实现图示 如上图所示: HashMap底层是由 数组+(链表)+(红黑树) 组成,每个存储在HashMap中的键值对都存放在一个Node节点之中,其中包含了Key-Value ...
 - 【JAVA集合】HashMap源码分析(转载)
		
原文出处:http://www.cnblogs.com/chenpi/p/5280304.html 以下内容基于jdk1.7.0_79源码: 什么是HashMap 基于哈希表的一个Map接口实现,存储 ...
 - JDK1.8 HashMap源码分析
		
一.HashMap概述 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时 ...
 
随机推荐
- Asp.Net在线预览Word文档的解决方案与思路
			
前几天有个老项目找到我,有多老呢?比我工作年限都长,见到这个项目我还得叫一声前辈. 这个项目目前使用非常稳定,十多年了没怎么更新过,现在客户想加一个小功能:在线预览Word文档. 首先想到的是用第三方 ...
 - Bugku CTF练习题---加密---凯撒部长的奖励
			
Bugku CTF练习题---加密---凯撒部长的奖励 flag:SYC{here_Is_yOur_rEwArd_enjOy_It_Caesar_or_call_him_vIctOr_is_a_Exc ...
 - python mysqldb 报错: ProgrammingError: must be real number, not str 解决
			
代码: sql = 'insert into book(book_name,book_desc,origin_price,publish_id,tag_id,book_img) values(%s,% ...
 - 最佳案例 | QQ 相册云原生容器化之路
			
关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...
 - deepin安装jdk配置环境
			
下载一个jdk压缩包https://download.oracle.com/java/18/latest/jdk-18_linux-x64_bin.tar.gz 这个包,不用安装,下下来,直接解压,然 ...
 - wsgiref模块、web框架、django框架简介
			
"""web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...
 - RabbitMQ 3.9( 续 )
			
前言 基础篇链接:https://www.cnblogs.com/xiegongzi/p/16229678.html 3.9.延迟队列 - 重要 3.9.1.延迟队列概念 这个玩意儿要表达的意思其实已 ...
 - Golang:将日志以Json格式输出到Kafka
			
在上一篇文章中我实现了一个支持Debug.Info.Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手.有兴趣的可以通过这个链接前往:https://github.com/ ...
 - EFCore常规操作生成的SQL语句一览
			
前言 EFCore的性能先不说,便捷性绝对是.Net Core平台下的ORM中最好用的,主要血统还百分百纯正. EFCore说到底还是对数据库进行操作,无论你是写Lamda还是Linq最后总归都是要生 ...
 - CentOS下Python管理
			
一.升级Python 查看系统版本 cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 查看Python版本 python -V ...