Hashtable的原理,并说出HashMap与Hashtable的区别
程序员文章站
2022-05-12 10:55:38
...
HashTable
Hashtable 是一个散列表,与HashMap相同,它存储的内容是键值对(key-value)映射。
Hashtable 方法都是synchronized修饰的,说明Hashtable是线程安全的,
它的key、value都不可以为null。
Hashtable<String, Object> map = new Hashtable<>();
底层调用方法如下:
默认创建时,hashtable的默认容量为11,加载因子为0.75,
扩容:newsize = olesize*2+1
,加载因子过高虽然减少了空间开销,但同时也增加了查找某个条目的时间
/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
public Hashtable() {
this(11, 0.75f);
}
- 底层数组+链表实现,无论key还是value都不能为null,线程安全,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化
- 初始size为11,扩容:newsize = olesize*2+1
HashMap
- 底层数组+链表实现,可以存储null键和null值,线程不安全
- 初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂
- 扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
- 插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)
- 当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀
两者区别:
- HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。
- HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
- 另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
- 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
- HashMap不能保证随着时间的推移Map中的元素次序是不变的。
上一篇: 初识线程
下一篇: 【练】打印100~200 之间的素数
推荐阅读
-
java中Hashtable和HashMap的区别分析
-
HashMap和Hashtable的详细区别
-
Java自学-集合框架 HashMap和Hashtable的区别
-
HashTable与ConcurrentHashMap的区别
-
HashMap与Hashtable的区别 面试多线程框架
-
HashMap,LinkedHashMap,TreeMap,HashTable的区别 HashMapLinkedHashMapTreeMapHashTable
-
HashTable、ConcurrentHashMap、TreeMap、HashMap关于键值的区别
-
Hashmap、Hashtable、Arraylist的区别
-
Hashmap、Hashtable、Arraylist的区别
-
聊聊C# 中HashTable与Dictionary的区别说明