hashMap的具体实现
HashMap是Java中的一个重要的数据结构!
与HashMap更重要的一个数据结构是HashTable,其中最重要的区别是HashTable传说中是线程安全的(之所以说他是传说是因为我并没有去理解为什么,这是我的错,没有理解就搬上了讲台!)
HashMap的内部结构很简单,如下(图片来自importnews,专属java的一个实时blog.本文也一定程度上参考了importnews,之所有没有直接转载是因为我觉得,有些东西,你只是看到了,他并不属于你!而我要做的,就是消化它,达到可以有自己见解的地方,原文链接地址:http://www.importnew.com/10620.html)
在HashMap内部,实现存贮key-value键值对的是一个Entity的内部类,
static class Entry implements Map.Entry {final K key;V value;Entry next;final int hash;...//More code goes here } `
这个类可以构成一个链表,在key中的hashCode相同时,会构成一个链表,
这个类在HashMap中构成了一个table数组,所有的键值对就保留在这个键值对数组之中,这个数据默认的长度是16,当数据超过这个大小之后,会自动的真正增长,但是如果数据刚刚好处于增长的上边缘,也就是>=,会造成数据内存大浪费,一些文章推荐我们在使用一些集合类的时候要指定好它的大小,避免造成过大的内存泄漏
从我们平常使用的HashMap中我们可以得出,操纵HashMap只是通过put和get方法
1.了解put方法
public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<k , V> e = table[i]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}
对key做null检查。如果key是null,会被存储到table[0],因为null的hash值总是0。
key的hashcode()方法会被调用,然后计算hash值。hash值用来找到存储Entry对象的数组的索引。有时候hash函数可能写的 很不好,所以JDK的设计者添加了另一个叫做hash()的方法,它接收刚才计算的hash值作为参数。如果你想了解更多关于hash()函数的东西,可 以参考:hashmap中的hash和indexFor方法
indexFor(hash,table.length)用来计算在table数组中存储Entry对象的精确的索引。
在我们的例子中已经看到,如果两个key(这里指的是两个不同key值)有相同的hash值(也叫冲突),他们会以链表的形式来存储。所以,这里我们就迭代链表。
- 如果在刚才计算出来的索引位置没有元素,直接把Entry对象放在那个索引上。
- 如果索引上有元素,然后会进行迭代,一直到Entry->next是null。当前的Entry对象变成链表的下一个节点。
- 如果我们再次放入同样的key会怎样呢?逻辑上,它应该替换老的value。事实上,它确实是这么做的。在迭代的过程中,会调用equals() 方法来检查key的相等性(key.equals(k)),如果这个方法返回true,它就会用当前Entry的value来替换之前的value。
2.了解get
public V get(Object key) {if (key == null)return getForNullKey();int hash = hash(key.hashCode());for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k)))return e.value;}return null;}
你传递一个key从hashmap总获取value的时候:
对key进行null检查。如果key是null,table[0]这个位置的元素将被返回。
key的hashcode()方法被调用,然后计算hash值。
indexFor(hash,table.length)用来计算要获取的Entry对象在table数组中的精确的位置,使用刚才计算的hash值。
在获取了table数组的索引之后,会迭代链表,调用equals()方法检查key的相等性,如果equals()方法返回true,get方法返回Entry对象的value,否则,返回null。
总结:
- HashMap有一个叫做Entry的内部类,它用来存储key-value对。
- 上面的Entry对象是存储在一个叫做table的Entry数组中。
- table的索引在逻辑上叫做“桶”(bucket),它存储了链表的第一个元素。
- key的hashcode()方法用来找到Entry对象所在的桶。
- 如果两个key有相同的hash值,他们会被放在table数组的同一个桶里面。
- key的equals()方法用来确保key的唯一性。
- value对象的equals()和hashcode()方法根本一点用也没有。
转载于:https://www.cnblogs.com/rainiplus/p/3721998.html
hashMap的具体实现相关推荐
- 在js中使用HashMap数据结构,在js中使用K,V数据结构
首先是定义一个HashMap方法,做基类(复制在js中即可,然后引用) //简单的哈希表,begin function HashMap() {/** Map 大小 * */var size = 0;/ ...
- Map再整理,从底层源码探究HashMap
前言 本文为对Map集合的再一次整理.内容包括:Map HashMap LinkedHashMap TreeHashMap HashTable ConcurrentHashMap Map Map< ...
- HashMap 的长度为什么是 2 的幂次方?
HashMap 的长度为什么是 2 的幂次方? 为了能让HashMap存取高效,尽量减少碰撞,需要将散列表的数据分配均匀.使用HashMap查询或插入数据时,需要先对数组长度取模运算,index = ...
- 解决Apache CXF 不支持传递java.sql.Timestamp和java.util.HashMap类型问题
在项目中使用Apache开源的Services Framework CXF来发布WebService,CXF能够很简洁与Spring Framework 集成在一起,在发布WebService的过程中 ...
- hashmap value可以为空吗_美团面试题:Hashmap结构,1.7和1.8有哪些区别(最详细解析)...
作者|依本多情 原文:blog.csdn.net/qq_36520235/article/details/82417949 一.真实面试题之:Hashmap的结构,1.7和1.8有哪些区别 不同点: ...
- hashmap实现原理_Java中HashMap底层实现原理(JDK1.8)源码分析
在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依 ...
- android 设置setmultichoiceitems设置初始化勾选_阿里巴巴Java开发手册建议创建HashMap时设置初始化容量,但是多少合适呢?...
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生. 关于HashMap,很多人都对他有一些基本的了解,比如他和hashtab ...
- HashMap 和 Hashtable 的 6 个区别,最后一个没几个人知道!
HashMap 和 Hashtable 是 Java 开发程序员必须要掌握的,也是在各种 Java 面试场合中必须会问到的. 但你对这两者的区别了解有多少呢? 现在,栈长我给大家总结一下,或许有你不明 ...
- transient HashMap使用目的分析
看HashSet源码有这么一句: private transient HashMap<E,Object> map; 再看HashSet的Add方法: 实际上HashSet是复用HashMa ...
- 调试JDK源码-一步一步看HashMap怎么Hash和扩容
调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hash ...
最新文章
- 深度linux卡在扫描硬盘,linux使用badblocks命令扫描硬盘排除故障
- redis--Sentinel
- 以Java的视角来聊聊BIO、NIO与AIO的区别
- k8s-16-k8s基础存储
- 研发手Q推广遇到的一系列问题
- 最新阿里聚划算Java 5轮面试题,涵盖GC收集器、多线程锁等
- Poj_1325 Machine Schedule -最大匹配性质题目
- vuejs 指令封装 button 加载效果_这些Vue自定义指令,让你的项目开发爽到爆
- windows server 2008 安装linux,使用WSL在Windows Server 2019上运行Linux的方法
- 【已解决】显示屏没有问题,主机电源键按不开机怎么办?
- 如何消除选定TextBox后的光标但又不失去焦点。
- logo字体在线设计工具
- 神经+符号知识推理论文浅读4篇
- 打乱数组 matlab,matlab对数组前N个数求和
- 华硕笔记本(GTX 1060显卡)安装Ubuntu16.04+Nvidia显卡驱动+Cuda8.0+cudnn6.0+ROS+Opencv3.2+Caffe+Tensorflow
- 【Matlab】曲线拟合
- 电子邮件服务器匿名转发功能吗,你为什么不能匿名发送电子邮件
- 航班延误来领钱,信用卡航班延误险最全攻略(2018年版)
- asp.net nancy_如何在ASP.Net Core中使用Nancy
- 给在读研究生未来要读研同学们的一封受益匪浅的信
热门文章
- python读取txt每一行存入数组
- 你知道如何计算CNN感受野吗?这里有一份详细指南
- leetcode——给你两个非空链接表,代表两个非负整数。 数字以相反的顺序存储,并且它们的每个节点包含单个数字。 将两个数字相加,并将其作为链表返回。
- 如何使用优化算法手动拟合回归模型
- 2021年各省高考试成绩查询,2021年各省高考成绩查询时间 什么时候出分
- STM 事务 ACID
- Hyperledger Fabric的工作流程
- 区块链 Fisco bcos 智能合约(11)-深入浅出Solidity
- python判断是否为素数的函数 是返回字符串yes_编写函数,判断一个数字是否为素数,是则返回字符串 YES ,否则返回字符串 NO 。_学小易找答案...
- 【mybatisPlus】mybatis基本使用