hash-2.hashMap
1.HashMap的数据结构
a.HashMap是一个链表散列的结合体,即,数组和链表的结合体。
b.HashMap类中定义了Entry类型的数组,Entry [ ] ,Entry有key value hash next属性
如代码
transient Entry[] table; static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
……
}
c.结构图如图:
d.HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,
就会初始化一个数组。table数组的元素是Entry类型的。
每个 Entry元素其实就是一个key-value对,并且它持有一个指向下一个 Entry元素的引用
,这就说明table数组的每个Entry元素同时也作为某个Entry链表的首节点,
指向了该链表的下一个Entry元素,这就是所谓的“链表散列”数据结构,即数组和链表的结合体。
2.HashMap的存储实现
当我们往HashMap中put元素的时候,先根据key的重新计算元素的hashCode,
根据hashCode得到这个元素在table数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,
最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。
代码:
public V put(K key, V value) {
// HashMap允许存放null键和null值。
// 当key为null时,调用putForNullKey方法,将value放置在数组第一个位置。
if (key == null)
return putForNullKey(value);
// 根据key的keyCode重新计算hash值。
int hash = hash(key.hashCode());
// 搜索指定hash值在对应table中的索引。
int i = indexFor(hash, table.length);
// 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素。
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// 如果发现 i 索引处的链表的某个Entry的hash和新Entry的hash相等且两者的key相同,则新Entry覆盖旧Entry,返回。
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// 如果i索引处的Entry为null,表明此处还没有Entry。
modCount++;
// 将key、value添加到i索引处。
addEntry(hash, key, value, i);
return null;
3.读取元素
从HashMap中get元素时,首先计算key的hashCode,找到数组中对应位置的某一元素,
然后通过key的equals方法在对应位置的链表中找到需要的元素。
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;
}
4.归纳起来简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,
这个整体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,
当需要存储一个 Entry 对象时,会根据hash算法来决定其在数组中的存储位置,
在根据equals方法决定其在该数组位置上的链表中的存储位置。
hash-2.hashMap的更多相关文章
- hash算法 (hashmap 实现原理)
Hash ,一般翻译做" 散列" ,也有直接音译为" 哈希" 的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出 ...
- Hash及HashMap简介
Hash简介: Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射 ...
- HashMap的内部实现机制,Hash是怎样实现的,什么时候ReHash
1.HashMap的内部实现机制 HashMap是对数据结构中哈希表(Hash Table)的实现,Hash表又叫散列表.Hash表是根据关键码Key来访问其对应的值Value的数据结构,它通过一个映 ...
- hashCode及HashMap中的hash()函数
一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构 ...
- [ 转载 ]hashCode及HashMap中的hash()函数
hashCode及HashMap中的hash()函数 一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是 ...
- 学习Redis你必须了解的数据结构——HashMap实现
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文链接博客园蜗牛 cnblogs.com\tdws . 首先提供一种获取hashCode的方法,是一种比较受欢迎的方式,该方法参照了一位园友的 ...
- HashMap 源码解析
HashMap简介: HashMap在日常的开发中应用的非常之广泛,它是基于Hash表,实现了Map接口,以键值对(key-value)形式进行数据存储,HashMap在数据结构上使用的是数组+链表. ...
- 关于Android中ArrayMap/SparseArray比HashMap性能好的深入研究
由于网上有朋友对于这个问题已经有了很详细的研究,所以我就不班门弄斧了: 转载于:http://android-performance.com/android/2014/02/10/android-sp ...
- [转] HashMap的存取之美
本文转自 http://www.nowamagic.net/librarys/veda/detail/1202 HashMap是一种十分常用的数据结构,作为一个应用开发人员,对其原理.实现的加深理解有 ...
- hdu5183 hash大法
维护前缀和sum[i]=a[0]-a[1]+a[2]-a[3]+…+(-1)^i*a[i]枚举结尾i,然后在hash表中查询是否存在sum[i]-K的值.如果当前i为奇数,则将sum[i]插入到has ...
随机推荐
- JavaWeb学习总结-09 JDBC 学习和使用
一 JDBC相关概念介绍 1.1 数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...
- rhino(犀牛) --- color control
create color materials, if "材料赋予方式" is "图层", the color of "材质" is show ...
- 使用chrome查看网页上效果的实现方式
使用chrome查看网页上效果的实现方式 chrome是一个极为强大的工具,很多时候,我们不知道一个效果怎么实现的,我们完全可以找到响应的网页,然后找到其html文件,和js文件,查看源码,获得其实现 ...
- Hibernate 配置文件与映射文件 总结
hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 一.Hibernate配置文件详解 Hibernate配置文件有两种形式:XML与p ...
- SQL查询效率:100w数据查询只需要1秒钟
G os: windows 数据库: ms sql server 目的: 查询性能测试,比较两种查询的性能 SQL查询效率 step by step -- setp . -- 建表 create ta ...
- Bois设置教程
BIOS设置图解教程之Award篇 (目前主板上常见的BIOS主要为AMI与AWARD两个系列,如何辨别BIOS品牌系列请移步,本文详细讲解Award系列的BIOS设置图解教程,如果你的BIOS为AM ...
- lua 元表
Set = {} Set.mt = {} function Set.new(t) local set = {} setmetatable(set, Set.mt) for _, l in ipairs ...
- centos设置编码
CentOS6.5解决中文乱码与设置字符集 Windows的默认编码为GBK,Linux的默认编码为UTF-8.在Windows下编辑的中文,在Linux下显示为乱码.为了解决此问题,修改Linux的 ...
- ubuntu 安装php7.1
sudo apt-get update sudo apt-get install -y language-pack-en-base locale-gen en_US.UTF-8 sudo apt-ge ...
- 9月6日表格标签(table、行、列、表头)(补)
一.<table> <table>代表表格标签. <table></table> 1.width 表示表格宽度,宽度表达方式有像素和百分比两种.网 ...