HashMap
什么是hash
散列法(Hashing)或哈希法是一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法。==简单来讲就是将任意长度的二进制映射到固定长度的较小的二进制,而这个较小的二进制是由hash算法来生成。== 在简单点就是像是查字典,只不过是字典里的查询不是a,b,c,d而是hashcode。而这个hashcode就有是较短的二进制。
什么是map
map即映射,也就是平时说的key-value键值对,entry:也是key,value的形式存储的,有了entry后从map里取值,赋值上更方便[对象操作对象](查了好多资料都是这样说的,而且好多实现都是把值存到entry中,在存到map里,而jdk8用的不是entry用的是node,而对hash算法,也是对entry或者是node的使用进行了hash而对map本身没有影响)什么是hashMap,也就是使用了hash算法的map
但是在代码实现就不是那么简单了。
Java中的hashMap中的数据存储是由数组和链表实现的。- 数组:组是在内存中开辟一段连续的空间,因此,只要知道了数组首个元素的地址,在数组中寻址就会非常容易,其时间复杂度为O(1)。但是当要插入或删除数据时,时间复杂度就会变为O(n)。
- 链表: 是内存中一系列离散的空间,其插入和删除操作的内存复杂度为O(1),但是寻址操作的复杂度却是O(n)。那有没有一种方法可以结合两者的优点,即寻址,插入删除都快呢?这个方法就是HashMap。
- 散列函数:将数据的hashCode映射到散列表中的位置,此过程不需给出冲突解决方案。好的散列函数的2个必备条件:1,快捷,在O(1)时间内运行;2,均匀的分布hashCode,填充概率相同。
- 冲突解决方案(collisionsolution):当一个新项散列到已经被占据的散列表中的位置时,被告之发生冲突,解决方案用于确定新项可以插入散列表中未被占据的位置。解决冲突主要的主要方法:开放寻址方法(寻找另外的空位);封闭寻址方法(吊挂另一种数据结构)一般采用后者挂链表的方式。
- 再散列(rehash):当数据的容量大于散列表的容量的容量时,那么创建一张指定新容量的表,再将原来表中的数据映射到新表中。
- java.util.HashMap是很常见的类,实现了java.util.Map<K,V>接口
HashMap主要是用数组来存储数据的,我们都知道它会对key进行哈希运算,
哈系运算会有重复的哈希值,对于哈希值的冲突,HashMap采用链表(挂链)来解决的。
Entry就是HashMap存储数据所用的类,相当于链表的节点。它拥有的属性如下
Java代码1
2
3
4
5
6static class Entry implements Map.Entry {
final K key;
V value;
Entry next;
int hash;
}看到next了吗?next就是为了哈希冲突而存在的。比如通过哈希运算,一个新元素应该在数组的第10个位置,但是第10个位置已经有Entry,那么好吧,将新加的元素也放到第10个位置,将第10个位置的原有Entry赋值给当前新加的 Entry的next属性。数组存储的是链表,链表是为了解决哈希冲突的。
** 后记 ** 这种一般在其他的包装类也可以看得到如arrayList中的 elementData。也是用来存放数据的。包装类只不过是帮你把一些操作封装了,相关操作,方便我们使用。