hash表的理解
-
首先我们先明白什么是 hash
-
比如一个map集合中取出所有的key集合,将这个集合中每一个元素通过一定的算法(f),将这个不确定长度的集合的每个元素,映射到一个固定长度的数组当中.(通常key集合的长度远远大于数组的长度)
-
将key集合中的元素k----->通过f函数算法------>得到在数组中的位置,这给位置我们叫做f(k)
-
把k转化为f(k)的过程,称为hash的过程
-
-
上述的hash过程称作 散列
-
把key集合映射后的表称为:散列表或者hash表,哈希表,hash_table
-
hash表中固定长度的数组称为散列地址
-
经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(Uniform Hash function)
-
hash算法有md4,md5等,
-
基于哈希表的 Map 接口的实现。就是hashMap集合
-
HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。
-
初始容量:即使初始固定数组的长度
-
加载因子(初始加载因子为0.75),比如数组长度为100 ,当数组中存入75个元素时或超过75时,要对hash表进行rehash(重建内部数据结构)并将数组长度扩容为原来的2倍
-
-
当重写equals()方法时必须重写hashcode()方法
-
无限长度的k集合,放入有限长度的hash表的散列地址中,必然会有不同的k映射为相同的散列地址
-
(如果equals没有被重写的话)equals()相等必须有相等的hashcode()值
-
equals()不相等,hashcode()可能相等
-
hashcode()值不相等,equeals可定不相等.
-
当我们重写equals而没有重写hashcode时
-
就可能会出现equals相等但是hashcode值却不相等,违背的上述的第一条原则.
-
hashcode()不相等,但是equeals却相等的情况
-
-
有可能会移除不了元素,严重时导致内存泄漏。
-
-
hashMap在jdk1.7与jdk1.8中的原理及不同
- Jdk1.7数组+链表形式
- Jdk1.8 数组+链表/红黑树
- 散列表长度不大于8,链表长度达到8,首先进行,resize数组扩容
- 如果散列表长度大于64,链表长度到达8,就会把链表结构转化成红黑树结构
-
Map家族
-
ConcurrentHashMap
- 线程安全
- 实现更加精细,对map集合中的桶加锁
- 采用分段锁,默认Segment[]的数组长度16
-
LinkedHashMap
- 会记录集合元素的插入顺序
- Iterator先进先出
- 遍历会比hashMap慢,遍历速度之和元素个数有关,与容量无关
-
TreeMap
- 是一个有序的key-value集合,它是通过红黑树实现的
- Key不能为null,因为null不能参与排序
- 创建一个空TreeMap,keys按照自然排序
- 添加、删除和定位映射关系上,TreeMap类要比HashMap类的性能差一些
-
Hashtable
- 线程安全,方法几乎都是同步的
- 效率<CurrentHashMap<HashMap
- Key和vlue都不能为null
-
HashMap
- 基于hash表的Map集合,数组加链表结构---->jdk1.7与1.8的区别
- 线程不安全----->HashMap/CurrentHashMap
- 默认无规则排序----->LinkedHashMap(先进先出)
- 能自定义排序------>TreeMap