2020.7.24
宜 放松心情
忌 过分焦虑
预计阅读完需要 1<<4 分钟。 不了解HashMap的可以移步 HashMap ,先有个大概了解。 简单介绍: 1.HashMapHashMap是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键,HashMap 的实例有两个参数影响其性能:初始容量 16 和加载因子0.75。
HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。
HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
Hashtable也是JDK1.0引入的类,是线程安全的,能用于多线程环境中。
Hashtable同样实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆。
初始容量11 和加载因子0.75。
1、继承的父类不同
HashMap继承自AbstractMap类,但二者都实现了Map接口。Hashtable继承自Dictionary类。
public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable {
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable {
使用选择需要多方面考虑,比如
存储扩容,以及线程安全问题!
2、线程安全问题
结论:HashTable 线程安全;HashMap 线程不安全。
HashMap是非synchronized,HashTable是synchronized的;
单线程情况下,不需要进行同步,此时HashMap的性能要高于HashTable;
HashMap是不同步的,但是我们可以使用Collections这个集合操作类来使HashMap保持同步,具体方法是
在JDK1.5中,新增了ConcurrentHashMap类,是线程安全的HashMap,可以用来替代HashTable,而且扩展性也比HashTable好。
![66afc70c083fd5c5bbd12f286b11d296.png](https://img-blog.csdnimg.cn/img_convert/66afc70c083fd5c5bbd12f286b11d296.png)
![80a53699027cf7d6e698ac2d8d9979a3.png](https://img-blog.csdnimg.cn/img_convert/80a53699027cf7d6e698ac2d8d9979a3.png)
3、计算hash值方式不同
HashMap有个hash方法重新计算了key的hash值,因为hash冲突变高,所以通过一种方法重算hash值。
// hashmap
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// hashtableint hash = key.hashCode();int index = (hash & 0x7FFFFFFF) % tab.length;// &0x7FFFFFFF的目的是为了将负的hash值转化为正值,因为hash值可能为负数,// 而&0x7FFFFFFF后,只有符号位改变,而后面的位都不变。
4、扩容方式不同
HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
// Hashtable
// overflow-conscious code
int newCapacity = (oldCapacity <
// HashMap
newThr = oldThr << 1; // double threshold
5、新增元素的要求
HashMap:key,value都可以为null
HashTable:key,value都不可以为null
HashTable: key,value任意一个为null,主线程都会抛出NullPointerException
6、解决hash冲突方式不同(地址冲突)对于HashMap
jdk8以前:使用链地址法(拉链法)
jdk8开始:
1.如果冲突数量小于等于8,则是以链表方式解决冲突。
2.而当冲突大于8时且数组size>64,就会将冲突的Entry转换为红黑树进行存储。
3.而又当数量小于6时,则又转化为链表存储。
而在Hashtable中, 都是以链表方式存储。
7、遍历方法也不一样
HashMap:iterator
Hashtable:enumeration
关于这两个其实还有很多可以深究....今天先到这