亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Hashtable源碼分析_JDK1.8版本

tunny / 2133人閱讀

摘要:簡介聲明文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處聲明和一樣也是散列表,存儲(chǔ)元素也是鍵值對(duì)繼承于類類聲明了操作鍵值對(duì)的接口方法,實(shí)現(xiàn)接口定義鍵值對(duì)接口大部分類用修飾,證明是線程安全的基本數(shù)據(jù)結(jié)構(gòu)鍵值對(duì)數(shù)組,每個(gè)本質(zhì)上是一個(gè)單向鏈表的表頭閾值裝填因

Hashtable簡介 聲明

文章均為本人技術(shù)筆記,轉(zhuǎn)載請(qǐng)注明出處https://segmentfault.com/u/yzwall

Hashtable聲明

public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable

Hashtable和HashMap一樣也是散列表,存儲(chǔ)元素也是鍵值對(duì);
Hashtable繼承于Dictionary類(Dictionary類聲明了操作鍵值對(duì)的接口方法),實(shí)現(xiàn)Map接口(定義鍵值對(duì)接口);
Hashtable大部分類用synchronized修飾,證明Hashtable是線程安全的;

Hashtable基本數(shù)據(jù)結(jié)構(gòu)

private transient Entry[] table:鍵值對(duì)/Entry數(shù)組,每個(gè)Entry本質(zhì)上是一個(gè)單向鏈表的表頭

private int threshold:rehash閾值

private float loadFactor:裝填因子

private transient int modCount = 0: Hashtable結(jié)構(gòu)化修改次數(shù),用來實(shí)現(xiàn)fail-fast機(jī)制;

private transient volatile Set> entrySet:Hastable視圖,鍵值對(duì)集合;

private transient volatile Set keySetHastable視圖,key集,Hashtable中key不可重復(fù);

private transient volatile Collection valuesHastable視圖,value集合,可重復(fù);

Hashtable中key和value是一對(duì)多關(guān)系;

鍵值對(duì)/Entry
private static class Entry implements Map.Entry {
    final int hash;
    final K key;
    V value;
    Entry next;
    ...
    // 計(jì)算鍵值對(duì)的hashCode
    public int hashCode() {
        // "^" 按位異或, hash在調(diào)用構(gòu)造器時(shí)傳入
        return hash ^ Objects.hashCode(value);
    }
}
Hash函數(shù)

鍵值對(duì)

Hashtable方法分析 public synchronized boolean contains(Object value)

public boolean containsValue(Object value)內(nèi)部調(diào)用contains(value);

判斷是否含有該value的鍵值對(duì),在Hashtable中hashCode相同的Entry用鏈表組織,hashCode不同的存儲(chǔ)在Entry數(shù)組table中;

// in contains() method.
Entry tab[] = table;
// 查找:遍歷所有Entry鏈表
for (int i = tab.length ; i-- > 0 ;) {
    for (Entry e = tab[i] ; e != null ; e = e.next) {
        if (e.value.equals(value)) {
            return true;
        }
    }
}
return false;
public synchronized boolean containsKey(Object key)
散列分布策略

int index = (hash & 0x7FFFFFFF) % tab.length;
計(jì)算鍵值對(duì)的桶位(本質(zhì)是鍵值對(duì)在tab數(shù)組中的索引),Hashtable本質(zhì)上采用除數(shù)取余法進(jìn)行散列分布,模運(yùn)算效率較低

Hash函數(shù)

int hash = key.hashCode() Hashtable直接調(diào)用key的hashCode()計(jì)算hashCode;

containsKey方法體
Entry tab[] = table;
int hash = key.hashCode();
/**
 * 計(jì)算index, % tab.length防止數(shù)組越界
 * index表示key對(duì)應(yīng)entry所在鏈表表頭
 */
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry e = tab[index] ; e != null ; e = e.next) {
    if ((e.hash == hash) && e.key.equals(key)) {
        return true;
    }
}
return false;

public synchronized V get(Object key):根據(jù)指定key查找對(duì)應(yīng)value,查找原理與containsKey相同,查找成功返回value,否則返回null;

public synchronized V put(K key, V value)

設(shè)置鍵值對(duì),key和value都不可為null,設(shè)置順序:

如果Hashtable含有key,設(shè)置(key, oldValue) -> (key, newValue);

如果Hashtable不含有key, 調(diào)用addEntry(...)添加新的鍵值對(duì);

private void addEntry(int hash, K key, V value, int index)

當(dāng)鍵值對(duì)個(gè)數(shù)超過閾值,先進(jìn)行rehash然后添加entry,否則直接添加entry;

public synchronized V remove(Object key)

remove操作,計(jì)算key所在鏈表表頭table[index],然后進(jìn)行單向鏈表的節(jié)點(diǎn)刪除操作

public synchronized Object clone()

對(duì)Hashtable的淺拷貝操作,淺拷貝所有bucket(單向鏈表組織形式)的表頭;

protected void rehash()

當(dāng)Hashtable中鍵值對(duì)總數(shù)超過閾值(容量*裝載因子)后,內(nèi)部自動(dòng)調(diào)用rehash()增加容量,重新計(jì)算每個(gè)鍵值對(duì)的hashCode;
int newCapacity = (oldCapacity << 1) + 1計(jì)算新容量 = 2 * 舊容量 + 1;并且根據(jù)新容量更新閾值;

...
for (int i = oldCapacity ; i-- > 0 ;) {
    // 拷貝每個(gè)Entry鏈表
    for (Entry old = (Entry)oldMap[i] ; old != null ; ) {
        Entry e = old;
        old = old.next;
        // 重新計(jì)算每個(gè)Entry鏈表的表頭索引(rehash)
        int index = (e.hash & 0x7FFFFFFF) % newCapacity;
        // 開辟鏈表節(jié)點(diǎn)
        e.next = (Entry)newMap[index];
        // 拷貝
        newMap[index] = e;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/66972.html

相關(guān)文章

  • 集合框架源碼學(xué)習(xí)之HashMap(JDK1.8)

    摘要:所謂拉鏈法就是將鏈表和數(shù)組相結(jié)合。若遇到哈希沖突,則將沖突的值加到鏈表中即可。在編寫程序中,要盡量避免。 目錄: 0-1. 簡介 0-2. 內(nèi)部結(jié)構(gòu)分析   0-2-1. JDK18之前   0-2-2. JDK18之后 0-3. LinkedList源碼分析   0-3-1. 構(gòu)造方法   0-3-2. put方法   0-3-3. get方法   0-3-4. resize方法 ...

    yangrd 評(píng)論0 收藏0
  • 這幾道Java集合框架面試題在面試中幾乎必問

    摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長度大于閾值默認(rèn)為時(shí),將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時(shí)間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...

    bigdevil_s 評(píng)論0 收藏0
  • HashMap源碼分析(一):JDK源碼分析系列

    摘要:當(dāng)一個(gè)值中要存儲(chǔ)到的時(shí)候會(huì)根據(jù)的值來計(jì)算出他的,通過哈希來確認(rèn)到數(shù)組的位置,如果發(fā)生哈希碰撞就以鏈表的形式存儲(chǔ)在源碼分析中解釋過,但是這樣如果鏈表過長來的話,會(huì)把這個(gè)鏈表轉(zhuǎn)換成紅黑樹來存儲(chǔ)。 正文開始 注:JDK版本為1.8 HashMap1.8和1.8之前的源碼差別很大 目錄 簡介 數(shù)據(jù)結(jié)構(gòu) 類結(jié)構(gòu) 屬性 構(gòu)造方法 增加 刪除 修改 總結(jié) 1.HashMap簡介 H...

    wdzgege 評(píng)論0 收藏0
  • JDK源碼(容器篇)

    摘要:三系列用于保存鍵值對(duì),無論是,還是已棄用的或者線程安全的等,都是基于紅黑樹。是完全基于紅黑樹的,并在此基礎(chǔ)上實(shí)現(xiàn)了接口??梢钥吹?,只有紅黑樹,且紅黑樹是通過內(nèi)部類來實(shí)現(xiàn)的。 JDK容器 前言 閱讀JDK源碼有段時(shí)間了,準(zhǔn)備以博客的形式記錄下來,也方便復(fù)習(xí)時(shí)查閱,本文參考JDK1.8源碼。 一、Collection Collection是所有容器的基類,定義了一些基礎(chǔ)方法。List、Se...

    Soarkey 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<