从源码来理解HashMap和HashSet

HashMap类

HashMap 内有一个table数组存放<K,V>,用关键字transient,则说明HashMap的table数组值是存放在内存中,不作为序列化数据保存。

put函数

如果key==null,

注意:table是一个数组,而这个数组下每个元素的下面其实是个链表,都是通过hash(key)得到相同k位置(table[k])

空值统一放在table的0位置,先遍历table[0]下的所有元素,如果插入的key==null,则将原本Entry的value替换,返回之前的值(oldValue)。

如果key!=null

根据key求出hash值,然后再让hash与table.length做相与运算,求得i在0-table.length-1中,然后根据i的位置,遍历table[i]下的链表,如果其下的元素key值与插入的key值相等的话则把原来key所对应的value值改成插入的value值,返回oldValue,如果旗下的元素key值遍历循环都没有与之相等,则添加一个Entry(addEntry(hash,key,value,i)).

在table[bucketIndex]中存放新的Entry对象,对象的next值存放原来的table[bucketIndex]对象,链表长度增加。

remove函数

如果key==null,hash为0(固定的,前面有说),否则就根据key求得hash值,然后相与运算得到i,prev为table[i]对象,遍历table[i]下的链表,判断如果key相等的话,如果它是首(也就是说table[i]------(pre == v)的情况),则让table[i]=next,如果它不是首else prev.next = next,直接连接下个元素,跳过中间元素,相当于删除(Java的gc机制,如果没有对象引用它的话,则会被回收掉),返回删除掉的e。循环结束后如果找不到找不到则返回null。

HashSet

HashSet本质是用HashMap来实现功能的。

PRESENT是随便new出来的Object,是一个final值,也就是说add加进去的每个Value都是一样的。

put函数又调用到前面所讲的HashMap里的put内,都是一样的

如果成功添加成功(addEntry后)则返回null,则add函数返回true,表示HashSet添加元素成功。

remove函数

本质也是调用HashMap的remove函数,

如果HashMap中有这个key的话则返回这个key对应的value,如果没有则返回null.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 10:00:34

从源码来理解HashMap和HashSet的相关文章

[JavaSE 源码分析] 关于HashMap的个人理解

目录 HashMap是什么? HashMap的底层数据结构是什么? table容量为什么必须是二的倍数? table容量怎么做到二的倍数? Entry是怎样的结构? Node: Entry在HashMap中的具体实现 处理hash冲突的方法 HashMap初始化或扩容 resize() HashMap计算元素的hash HashMap添加/更新元素 HashMap取值 HashMap删除元素 HashMap为什么是非线程安全的? HashMap在并发场景下可能存在哪些问题? 通过Debug来进一

【Java集合源码剖析】HashMap源码剖析

转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955 HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap. HashMap 实现了Serializable接口,因此它支持序列化,

storm源码之理解Storm中Worker、Executor、Task关系【转】

[原]storm源码之理解Storm中Worker.Executor.Task关系 Storm在集群上运行一个Topology时,主要通过以下3个实体来完成Topology的执行工作:1. Worker(进程)2. Executor(线程)3. Task 下图简要描述了这3者之间的关系:                                                    1个worker进程执行的是1个topology的子集(注:不会出现1个worker为多个topology服

JDK1.8源码学习之 HashMap.java

///JDK1.8源码学习之HashMap.java package java.util; import java.io.IOException; import java.io.InvalidObjectException; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.function.BiConsu

【Java集合源码剖析】HashMap源码剖析(转)

HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap. HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆. HashMap源码剖析 HashMap的源码如下(加入了比较详细的注释): [ja

hashMap 源码解读理解实现原理和hash冲突

hashMap 怎么说呢. 我的理解是 外表是一个set 数组,无序不重复 . 每个set元素是一个bean ,存着一对key value 看看代码吧 package test; import java.util.HashMap; import java.util.Map.Entry; public class HashMaptest { public static void main(String[] args) { HashMap<String, String> map = new Has

JDK1.8源码分析之HashMap(一)

一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也可以使用红黑树进行存储,总之,目标只有一个,那就是在安全和功能性完备的情况下让其速度更快,提升性能.好~下面就开始分析源码. 二.HashMap数据结构 说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率.所以可见

【集合框架】JDK1.8源码分析之HashMap(一) 转载

一.前言 在分析jdk1.8后的HashMap源码时,发现网上好多分析都是基于之前的jdk,而Java8的HashMap对之前做了较大的优化,其中最重要的一个优化就是桶中的元素不再唯一按照链表组合,也可以使用红黑树进行存储,总之,目标只有一个,那就是在安全和功能性完备的情况下让其速度更快,提升性能.好~下面就开始分析源码. 二.HashMap数据结构 说明:上图很形象的展示了HashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率.所以可见

[java源码解析]对HashMap源码的分析(二)

上文我们讲了HashMap那骚骚的逻辑结构,这一篇我们来吹吹它的实现思想,也就是算法层面.有兴趣看下或者回顾上一篇HashMap逻辑层面的,可以看下HashMap源码解析(一).使用了哈希表得"拉链法". 我打算按这个顺序来讲HashMap:几个关键属性 -> 构造方法-> 存取元素方法 ->解决hash冲突方法->HashMap扩容问题. 4个关键属性: /** *HashMap的存储大小 */ transient int size; /** * HashMa