经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
HashMap与Hashtable
来源:cnblogs  作者:那股泥石流  时间:2018/9/30 11:07:18  对本文有异议

HashMap与Hashtable数据结构几乎是相同的(数组+链表),核心方法的实现也大致相同

主要讨论不同,比较两者不同从JDK源码入手

一、父类不同

HashMap父类AbstractMap

Hashtable父类Dictionary

  Dictionary类源码已注释被弃用

  Hashtable类源码注释也表明Hashtable已被淘汰

  1. * Java Collections Framework</a>. Unlike the new collection
  2. * implementations, {@code Hashtable} is synchronized. If a
  3. * thread-safe implementation is not needed, it is recommended to use
  4. * {@link HashMap} in place of {@code Hashtable}. If a thread-safe
  5. * highly-concurrent implementation is desired, then it is recommended
  6. * to use {@link java.util.concurrent.ConcurrentHashMap} in place of
  7. * {@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的处理

  1. static final int hash(Object key) {
  2. int h;
  3. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  4. }

Hashtable不支持null

  1. public synchronized V put(K key, V value) {
  2. // Make sure the value is not null
  3. if (value == null) {// value==null抛异常
  4. throw new NullPointerException();
  5. }
  6. // Makes sure the key is not already in the hashtable.
  7. Entry<?,?> tab[] = table;
  8. int hash = key.hashCode();// key==null抛异常
  9. int index = (hash & 0x7FFFFFFF) % tab.length;
  10. @SuppressWarnings("unchecked")
  11. Entry<K,V> entry = (Entry<K,V>)tab[index];
  12. for(; entry != null ; entry = entry.next) {
  13. if ((entry.hash == hash) && entry.key.equals(key)) {
  14. V old = entry.value;
  15. entry.value = value;
  16. return old;
  17. }
  18. }
  19. addEntry(hash, key, value, index);
  20. return null;
  21. }

2、JDK1.8 HashMap引入了红黑树,链表超过最大长度(8),将链表改为红黑树再添加元素

3、hash碰撞之后的处理

  HashMap:在链表尾加入元素

  Hashtable:在链表头加入元素

  1.  

 

参考资料:

HashMap 和 HashTable 到底哪不同 ?

HashMap 与HashTable的区别  

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号