日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HashMap和Hashtable的区别总结

發(fā)布時(shí)間:2025/5/22 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HashMap和Hashtable的区别总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 前言
  • 源碼分析
    • 繼承關(guān)系的不同:
      • HashMap
      • Hashtable
    • 是否支持鍵值為null不同:
      • HashMap
      • Hashtable
    • 初始化和擴(kuò)容的方式不同:
      • Hashtable
      • HashMap
    • 計(jì)算 hash 值的方法不同:
      • HashTable
      • HashMap
    • 線(xiàn)程安全:
  • 總結(jié)


前言

提示:HashMap和Hashtable是我們常用的兩個(gè)Map集合,我們都知道Hashtable可以保證線(xiàn)程安全,但其實(shí)他們的源碼實(shí)現(xiàn)上野有很多不同的,下面我們就針對(duì)源碼對(duì)HashMap和Hashtable重寫(xiě)做一些研究。


提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

源碼分析

繼承關(guān)系的不同:

HashMap

HashMap 繼承 AbstractMap

public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable

Hashtable

HashTable 繼承 Dictionary

public class Hashtable<K,V>extends Dictionary<K,V>implements Map<K,V>, Cloneable, java.io.Serializable

是否支持鍵值為null不同:

HashMap

HashMap 允許 null 值(key 和 value 都可以)。這樣的鍵只能有一個(gè),可以有一個(gè)或者多個(gè)鍵所對(duì)應(yīng)的值為 null 。

public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

Hashtable

Hatable 不允許 null值(key 和 value 都不可以) key為 null 沒(méi)有 hash() ,value 為 null 的時(shí)候報(bào)異常

public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) { //value為null拋出NullPointerExceptionthrow new NullPointerException();}// Makes sure the key is not already in the hashtable.Entry<?,?> tab[] = table;int hash = key.hashCode();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;}private void addEntry(int hash, K key, V value, int index) {Entry<?,?> tab[] = table;if (count >= threshold) {// Rehash the table if the threshold is exceededrehash();tab = table;hash = key.hashCode();index = (hash & 0x7FFFFFFF) % tab.length;}// Creates the new entry.@SuppressWarnings("unchecked")Entry<K,V> e = (Entry<K,V>) tab[index];tab[index] = new Entry<>(hash, key, value, e);count++;modCount++;}

初始化和擴(kuò)容的方式不同:

Hashtable

public Hashtable() {this(11, 0.75f);//初始容量為11 } public Hashtable(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal Load: "+loadFactor);if (initialCapacity==0)initialCapacity = 1;this.loadFactor = loadFactor;table = new Entry<?,?>[initialCapacity]; // new 初始化數(shù)組threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); }

HashMap

HshMap的初始化在上偏文章中做了詳細(xì)介紹這里就好Hashtable()做比較就可以了
HashTable 在構(gòu)造方法里面進(jìn)行初始化,初始化大小為 11 每次擴(kuò)容的時(shí)候變?yōu)樵瓉?lái)的 2n+1 倍
HashMap調(diào)用默認(rèn)構(gòu)造是沒(méi)有初始化的 在第一次 調(diào)用 put 方法的時(shí)候,在 resize() 里面進(jìn)行初始化,初始化大小為 16, 每次擴(kuò)容后,變?yōu)樵瓉?lái)的 2倍

計(jì)算 hash 值的方法不同:

HashTable

public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) {throw new NullPointerException();}// Makes sure the key is not already in the hashtable.Entry<?,?> tab[] = table;int hash = key.hashCode(); // 直接調(diào)用算法int index = (hash & 0x7FFFFFFF) % tab.length; // 下標(biāo)計(jì)算@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; }

HashMap

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 計(jì)算得到 } final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {// 這個(gè)方法前面有 }

HashTable:直接調(diào)用 Object 的 hash() 函數(shù),計(jì)算出來(lái) hash 值,下標(biāo)直接 數(shù)組長(zhǎng)度取余得到
? int hash = key.hashCode();
? int index = (hash & 0x7FFFFFFF) % tab.length
Hash Map:首先 高位和低位異或得到 hash 值,然后 再和數(shù)組大小-1 做 與運(yùn)算 得到下標(biāo)
? int hash = key.hashCode() ^ (h >>> 16);
int index = (n - 1) & hash;

線(xiàn)程安全:

public synchronized V put(K key, V value) {// Make sure the value is not nullif (value == null) {throw new NullPointerException();}

HashTable的好多方法使用synchronized進(jìn)行加鎖操作保證了線(xiàn)程安全
HashMap 線(xiàn)程不安全

總結(jié)

1、繼承的父類(lèi)不一樣

HashTable :繼承 Dictionary HashMap:繼承AbstractMap

2、線(xiàn)程安全

HashTable:線(xiàn)程安全 HashMap:線(xiàn)程不安全

3、初始化的擴(kuò)容不一樣

HashTable:在構(gòu)造方法里面初始化,初始化大小為 11,每次擴(kuò)容 2n+1 倍 HashMap:在 put 值的時(shí)候進(jìn)行初始化,初始化大小為 16,每次擴(kuò)容 2倍

4、計(jì)算下標(biāo)的方法不同

HashTable:hash值 直接調(diào)用 Object 類(lèi)的HashCode() 方法,計(jì)算下標(biāo)直接對(duì)數(shù)組長(zhǎng)度取余 HashMap:hash值 是通過(guò) 高位和低位異或 得到,下標(biāo)通過(guò) 數(shù)組長(zhǎng)度 和 hash值進(jìn)行與運(yùn)算得到

5、鍵和值 的 null 取值不同

HashTable:鍵和值都不允許為 null HashMap:鍵和值都可以為 null,只能有唯一的鍵值為 null,可以有多個(gè)值為 null

總結(jié)

以上是生活随笔為你收集整理的HashMap和Hashtable的区别总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产原创在线观看 | 国产高清在线不卡 | 999黄色片 | 国产乱轮视频 | 日本精品三级 | av免费观看不卡 | www性| 综合成人 | 久久精品a亚洲国产v高清不卡 | 亚洲国产极品 | 成人激情av | 日本一二三不卡视频 | 福利视频在线播放 | 日本天堂网在线 | 欧美人与禽zozzo禽性配 | 小视频在线免费观看 | 国产成人手机视频 | 18成人免费观看视频 | 成人av番号网 | 伊人久久青青草 | 无码人妻精品一区二区蜜桃网站 | 日本真人做爰免费视频120秒 | 特级毛片av | 内射国产内射夫妻免费频道 | 日本三级中文字幕在线观看 | 亚洲福利久久 | 精品欧美视频 | 亚洲永久免费观看 | 澳门av在线 | va在线| 国产在线观看第一页 | 人妖一区二区三区 | 九九热这里有精品视频 | 成人自拍视频在线 | 亚洲成人资源 | 麻豆av网| 五月婷婷丁香综合 | 国产一区二区三区在线视频 | www.com在线观看 | 好男人.www | 国产日韩精品在线 | 一区二区三区精品视频在线观看 | 催眠调教艳妇成肉便小说 | 亚洲小视频网站 | a一级网站 | 人妻一区二区在线 | 日韩乱码视频 | 欧美精品一区二区三区久久 | xxxx国产精品 | 久久久亚洲天堂 | 日韩女同互慰一区二区 | 特级黄色一级片 | 好吊视频一区 | 大尺度一区二区 | 182av| www.欧美亚洲 | 99r热 | 天堂中文在线资源 | www在线观看视频 | 激情三级在线 | 国产毛毛片 | 女女互磨互喷水高潮les呻吟 | 懂色av一区二区三区四区五区 | 亚洲影音 | 亚洲s码欧洲m码国产av | 久久免费激情视频 | 久色88| 成年在线观看视频 | 在线观看你懂的网址 | 亚洲欧洲激情 | 成人免费看aa片 | 日韩欧美中文一区 | 亚洲精品在线一区二区 | 成人性生交大片免费看vrv66 | 成人在线免费看 | 成人午夜免费福利视频 | 欧美顶级少妇做爰hd | 欧美亚洲一 | 91av在线免费 | 久久精品二区 | 91蝌蚪视频在线观看 | 国产欧美高清 | 最新自拍偷拍 | 揉我啊嗯~喷水了h视频 | 人人妻人人爽一区二区三区 | 亚洲免费精品 | 欧美婷婷精品激情 | 91蝌蚪在线 | 日韩午夜片 | 国产又大又黑又粗免费视频 | 日韩经典一区 | 国产97免费视频 | 亚洲第一在线 | 亚洲免费在线看 | 人人妻人人藻人人爽欧美一区 | 久久久91精品国产一区二区三区 | 飘花影院伦理片 | 综合色影院 | 日本人与黑人做爰视频 |