摘要:簡介聲明文章均為本人技術筆記,轉載請注明出處聲明和一樣也是散列表,存儲元素也是鍵值對繼承于類類聲明了操作鍵值對的接口方法,實現接口定義鍵值對接口大部分類用修飾,證明是線程安全的基本數據結構鍵值對數組,每個本質上是一個單向鏈表的表頭閾值裝填因
Hashtable簡介 聲明
文章均為本人技術筆記,轉載請注明出處https://segmentfault.com/u/yzwall
Hashtable聲明public class Hashtable
extends Dictionary implements Map , Cloneable, java.io.Serializable
Hashtable和HashMap一樣也是散列表,存儲元素也是鍵值對;
Hashtable繼承于Dictionary類(Dictionary類聲明了操作鍵值對的接口方法),實現Map接口(定義鍵值對接口);
Hashtable大部分類用synchronized修飾,證明Hashtable是線程安全的;
private transient Entry,?>[] table:鍵值對/Entry數組,每個Entry本質上是一個單向鏈表的表頭
private int threshold:rehash閾值
private float loadFactor:裝填因子
private transient int modCount = 0: Hashtable結構化修改次數,用來實現fail-fast機制;
private transient volatile Set
private transient volatile Set
private transient volatile Collection
Hashtable中key和value是一對多關系;
鍵值對/Entryprivate static class EntryHash函數implements Map.Entry { final int hash; final K key; V value; Entry next; ... // 計算鍵值對的hashCode public int hashCode() { // "^" 按位異或, hash在調用構造器時傳入 return hash ^ Objects.hashCode(value); } }
鍵值對
Hashtable方法分析 public synchronized boolean contains(Object value)public boolean containsValue(Object value)內部調用contains(value);
判斷是否含有該value的鍵值對,在Hashtable中hashCode相同的Entry用鏈表組織,hashCode不同的存儲在Entry數組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;
計算鍵值對的桶位(本質是鍵值對在tab數組中的索引),Hashtable本質上采用除數取余法進行散列分布,模運算效率較低
int hash = key.hashCode() Hashtable直接調用key的hashCode()計算hashCode;
Entry,?> tab[] = table; int hash = key.hashCode(); /** * 計算index, % tab.length防止數組越界 * index表示key對應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):根據指定key查找對應value,查找原理與containsKey相同,查找成功返回value,否則返回null;
public synchronized V put(K key, V value)設置鍵值對,key和value都不可為null,設置順序:
如果Hashtable含有key,設置(key, oldValue) -> (key, newValue);
如果Hashtable不含有key, 調用addEntry(...)添加新的鍵值對;
當鍵值對個數超過閾值,先進行rehash然后添加entry,否則直接添加entry;
public synchronized V remove(Object key)remove操作,計算key所在鏈表表頭table[index],然后進行單向鏈表的節點刪除操作
public synchronized Object clone()對Hashtable的淺拷貝操作,淺拷貝所有bucket(單向鏈表組織形式)的表頭;
protected void rehash()當Hashtable中鍵值對總數超過閾值(容量*裝載因子)后,內部自動調用rehash()增加容量,重新計算每個鍵值對的hashCode;
int newCapacity = (oldCapacity << 1) + 1計算新容量 = 2 * 舊容量 + 1;并且根據新容量更新閾值;
... for (int i = oldCapacity ; i-- > 0 ;) { // 拷貝每個Entry鏈表 for (Entryold = (Entry )oldMap[i] ; old != null ; ) { Entry e = old; old = old.next; // 重新計算每個Entry鏈表的表頭索引(rehash) int index = (e.hash & 0x7FFFFFFF) % newCapacity; // 開辟鏈表節點 e.next = (Entry )newMap[index]; // 拷貝 newMap[index] = e; } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66972.html
摘要:所謂拉鏈法就是將鏈表和數組相結合。若遇到哈希沖突,則將沖突的值加到鏈表中即可。在編寫程序中,要盡量避免。 目錄: 0-1. 簡介 0-2. 內部結構分析 0-2-1. JDK18之前 0-2-2. JDK18之后 0-3. LinkedList源碼分析 0-3-1. 構造方法 0-3-2. put方法 0-3-3. get方法 0-3-4. resize方法 ...
摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時有了較大的變化,當鏈表長度大于閾值默認為時,將鏈表轉化為紅黑樹,以減少搜索時間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結系列第三周的文章。主要內容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區別 HashMap的底層...
摘要:當一個值中要存儲到的時候會根據的值來計算出他的,通過哈希來確認到數組的位置,如果發生哈希碰撞就以鏈表的形式存儲在源碼分析中解釋過,但是這樣如果鏈表過長來的話,會把這個鏈表轉換成紅黑樹來存儲。 正文開始 注:JDK版本為1.8 HashMap1.8和1.8之前的源碼差別很大 目錄 簡介 數據結構 類結構 屬性 構造方法 增加 刪除 修改 總結 1.HashMap簡介 H...
摘要:三系列用于保存鍵值對,無論是,還是已棄用的或者線程安全的等,都是基于紅黑樹。是完全基于紅黑樹的,并在此基礎上實現了接口。可以看到,只有紅黑樹,且紅黑樹是通過內部類來實現的。 JDK容器 前言 閱讀JDK源碼有段時間了,準備以博客的形式記錄下來,也方便復習時查閱,本文參考JDK1.8源碼。 一、Collection Collection是所有容器的基類,定義了一些基礎方法。List、Se...
閱讀 1958·2021-11-22 15:33
閱讀 3001·2021-11-18 10:02
閱讀 2603·2021-11-08 13:16
閱讀 1617·2021-10-09 09:57
閱讀 1366·2021-09-30 09:47
閱讀 2001·2019-08-29 13:05
閱讀 3064·2019-08-29 12:46
閱讀 1004·2019-08-29 12:19