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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Hashtable源码分析

發(fā)布時間:2024/10/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hashtable源码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)自https://blog.csdn.net/duoduo18up/article/details/80167074

1.定義

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

繼承自Dictionary。

  • Dictionary是一個抽象父類,功能和Map一樣,但過時了,官方推薦使用Map接口來替代。

實現(xiàn)了Map接口,以及Cloneable,Serializable接口。

2.和HashMap的區(qū)別

2.1 null值的問題

Hashtable的鍵(key)和值(value)均不能為null

/** * 將key和value加入到map中,明顯標(biāo)明, * value不能為null。如果key為null,則會報NullPointerException異常 * */ 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();//很直接的利用hashCode去除table.length,然后取長度。int index = (hash & 0x7FFFFFFF) % tab.length;@SuppressWarnings("unchecked")Entry<K,V> entry = (Entry<K,V>)tab[index];//鏈表后面有數(shù)據(jù)for(; entry != null ; entry = entry.next) {if ((entry.hash == hash) && entry.key.equals(key)) {//hash相同且equals,那么就連在后面,是用鏈表的方式。V old = entry.value;entry.value = value;return old;}}//第一個,鏈表后面沒有數(shù)據(jù)。addEntry(hash, key, value, index);return null; }

關(guān)于value,明顯有if判斷,不能為null。

如果key為null,則也直接在計算hashCode的時候就會報空指針異常。

2.2 計算table數(shù)組索引值的方法

int hash=key.hashCode();//直接用hashcode%n int index=(hash&0x7FFFFFFF)%tab.length

而HashMap中:

int index=e.hash%n;

hash值的計算方法不同,很直接地利用hashCode去除table.length,然后取余數(shù)。

2.3 Hashtable是線程安全的

因為Hashtable中的大多數(shù)方法都是加了synchronized關(guān)鍵字,所以同一時刻只能有一個線程進(jìn)入其方法,故是線程安全的。

2.4initialCapacity和loadFactor

HashMap中:initialCapacity=16,loadFactor=0.75;

Hashtable中:initialCapacity=11,loadFactor=0.75;

2.5解決沖突的方式

HashMap:鏈表/紅黑樹

  • 沖突數(shù)量<8,以鏈表方式解決沖突
  • 沖突數(shù)量>=8,將沖突的Entry轉(zhuǎn)換為紅黑樹進(jìn)行存儲
  • 又當(dāng)沖突數(shù)量<6時,有轉(zhuǎn)換為鏈表進(jìn)行存儲

Hashtable:只有鏈表

2.6 擴(kuò)容的額度

HashMap中:一旦擴(kuò)容,都是擴(kuò)展到2的倍數(shù)。因為這樣有利于計算數(shù)組索引值。即,和計算數(shù)組索引結(jié)合起來

Hashtable中:一次性擴(kuò)展為oldCapacity*2+1

/*** 一次擴(kuò)展是,old*2+1 */ @SuppressWarnings("unchecked") protected void rehash() {int oldCapacity = table.length;Entry<?,?>[] oldMap = table;// overflow-conscious codeint newCapacity = (oldCapacity << 1) + 1;if (newCapacity - MAX_ARRAY_SIZE > 0) {if (oldCapacity == MAX_ARRAY_SIZE)// Keep running with MAX_ARRAY_SIZE bucketsreturn;newCapacity = MAX_ARRAY_SIZE;}Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];modCount++;//新的threshold值。取newCapacity*loadFactor的小值。threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);table = newMap;for (int i = oldCapacity ; i-- > 0 ;) {for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {Entry<K,V> e = old;old = old.next;int index = (e.hash & 0x7FFFFFFF) % newCapacity;e.next = (Entry<K,V>)newMap[index];newMap[index] = e;}} }

先擴(kuò)展,再把就數(shù)組里面的元素一個一個添加到新的里面。

注意:這里取hash而不是e.hash,而仍然是key.hashCode計算保留下來的值。

總結(jié)

以上是生活随笔為你收集整理的Hashtable源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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