HashMap和HashTable都是集合类Map的子类
HashMap
HashMap是Map集合中最常用的子类
1.什么是HashMap
HashMap是继承AbstractMap,实现Map接口的一个采用哈希表来实现键值对的集合
2.HashMap特点
(1)底层实现
在jdk1.8之前,底层是通过链表+数组实现
在jdk1.8以后底层是通过链表+数组+红黑树实现
(2)实现了Map接口的全部方法
(3)HashMap的两个重要参数:“初始容量”和“加载因子”
这两个参数决定HashMap什么时候扩容
初始容量:数组的容量
加载因子:决定HashMap中元素占有多少比例时扩容,HashMap的默认加载因子为0.75
若加载因子过大发生冲突的可能性会增大,查找的效率会降低,若加载因子较小,会频繁发生rehash,这样性能又会降低
(4)HashMap线程不同步,线程不安全
(5)HashMap中的key和value是存储在Entry中,其中key和value可以为空,但是key为null只能有一个,且只能放在第一位,通过hashCode()方法和equals()方法来保证value值的唯一性
(6)HashMap中的元素是无序的,且顺序会不定时改变,因为底层是通过数组+链表实现的
(7)HashMap采用拉链法来解决哈希冲突
解决哈希冲突的方法:地址法,拉链法,开散列法
地址法:将相同hash值的对象组成一个链表放在hash值对应的位置
开放地址法:当冲突发生的时候,使用某种探测技术在散列表中形成一个探测序列,沿着这个序列逐个单元的查找,直到找到指定的关键字,或者碰到某个开放地址(即该地址单元为null)为止,再插入到开放的地址即可
拉链法:将所有关键字为同义词的节点链接在同一单链表中,若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0...m-1],凡是散列地址为i的节点,均插入到以T[i]为头指针的单链表中,T中各分量的初值均应为空指针,在拉链法中,填装因子a,可以大于1,但一般均取a<=1,拉链法适合未规定元素的大小
HashTable
HashTable是最早实现二元偶对象数据结构的,在后期添加了实现Map接口
HashTable特点
(1)底层实现
底层是通过数组实现的
(2)HashTable线程同步,线程安全
(3)HashTable中的key和value都不能为空,为了成功地在哈希表中存储和获取对象,用作键地对象必须实现hashCode()方法和equals()方法
HashMap和HashTable地区别
1.继承不同:
HashMap继承AbstractMap类,实现Map接口
HashTable继承Dictionary类实现Map接口
2.同步安全
HashMap中的方法在缺省情况下不同步,线程不安全
HashTable中的方法同步,线程安全
在多线程并发的情况下,可以直接使用HashTable,若使用HashMap需要进行同步处理
3.key与value
HashMap中key和value都可以为null,其中key只允许有一个为null,value可以有多个为null
HashTable中key和value都不允许出现null
因此HashMap中不能用get()方法来判断HashMap中是否存在某个键,而应该使用containsKey()方法来判断
4.遍历方式不同
HashMap和HashTable都使用Iterator,但是HashTable还使用了Enumeration的方式
5.哈希值的使用不同
HashMap需要重新计算hash值
HashTable直接使用hashCode
6.数组初始大小
HashMap中hash值默认大小为16,而且一定为2的指数
HashTable中hash值默认大小为11,增加的方式是old*2+1