HashMap与Hashtable
Posted hexinwei1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap与Hashtable相关的知识,希望对你有一定的参考价值。
HashMap与Hashtable数据结构几乎是相同的(数组+链表),核心方法的实现也大致相同
主要讨论不同,比较两者不同从JDK源码入手
一、父类不同
HashMap父类AbstractMap
Hashtable父类Dictionary
Dictionary类源码已注释被弃用
Hashtable类源码注释也表明Hashtable已被淘汰
* Java Collections Framework</a>. Unlike the new collection * implementations, {@code Hashtable} is synchronized. If a * thread-safe implementation is not needed, it is recommended to use * {@link HashMap} in place of {@code Hashtable}. If a thread-safe * highly-concurrent implementation is desired, then it is recommended * to use {@link java.util.concurrent.ConcurrentHashMap} in place of * {@code Hashtable}.
// 如果你不需要线程安全,那么使用HashMap,如果需要线程安全,那么使用ConcurrentHashMap。HashTable已经被淘汰了,不要在新的代码中再使用它。
二、Synchronize
Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。
HashMap不是线程安全的,在多线程并发的环境下,使用HashMap时就必须要自己增加同步处理。
(虽然HashMap不是线程安全的,但是它的效率会比Hashtable要好很多。这样设计是合理的。在我们的日常使用当中,大部分时间是单线程操作的。HashMap把这部分操作解放出来了。当需要多线程操作的时候可以使用线程安全的ConcurrentHashMap。ConcurrentHashMap虽然也是线程安全的,但是它的效率比Hashtable要高好多倍。因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。)
三、初始容量和扩充容量
HashMap初始容量16,扩容默认为原来容量的2倍
Hashtable初始容量11,扩容默认为原来容量的2倍+1
四、hash值算法不同
HashMap: 具体原因可参考JDK源码学习笔记——HashMap
1.int hash = (h = key.hashCode()) ^ (h >>> 16) ;
2.int index = (table.length - 1) & hash;
3.tableSizeFor()方法保证数组容量一定是2的次幂
Hashtable:
1.int hash = key.hashCode();
2.int index = (hash & 0x7FFFFFFF) % tab.length;
五、put时的不同
1、HashMap支持key==null value==null,hash方法专门有对key==null的处理
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
Hashtable不支持null
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) {// value==null抛异常 throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table; int hash = key.hashCode();// key==null抛异常 int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; }
2、JDK1.8 HashMap引入了红黑树,链表超过最大长度(8),将链表改为红黑树再添加元素
3、hash碰撞之后的处理
HashMap:在链表尾加入元素
Hashtable:在链表头加入元素
参考资料:
以上是关于HashMap与Hashtable的主要内容,如果未能解决你的问题,请参考以下文章
Java重点之小白解析--浅谈HashMap与HashTable