hashmap的存儲結構
『壹』 hashtable hashmap treeset treemap的存儲結構是什麼
hashset內部結構是使用hashmap實現的,當然是散列表。
treemap和treeset是樹形結構
『貳』 java中的hashmap是一種什麼數據結構
您好,提問者: HashMap 是一個散列表,它存儲的內容是鍵值對(key-value)映射。 當然,HashMap是一個不同步的類。 我們都知道迭代時候會轉換為Set,說明底層具備了Set的特性。 Set的底層結構:無序、根據HashCode判斷,如果HashCode一樣再去判斷
『叄』 hashmap是以什麼方式存儲數據 arraylist又是以什麼方式存儲數據
hashmap 實質上一個數組和鏈表的結合體,記得嚴尉敏版的C數據結構上將這個稱為「散列表」。對於hashmap存儲可以這樣理解,數組用於存儲key,鏈表用於存儲value,每個鏈表都鏈接在數組中的一個元素上。
arraylist 實質上就是一個順序的動態數組,開始時以一默認值開一數組,滿了後再擴容,且實現了動態添加和刪除。
二者性能區別:hashmpa 用於快速查找,但是arraylist基本上不浪費空間。各有利弊吧
『肆』 android中hashmap是什麼意思有什麼作用
在認識hashmap中要先認識Map。在數組中我們是通過數組下標來對其內容索引的,而在Map中我們通過對象來對對象進行索引,用來索引的對象叫做key,其對應的對象叫做value。
HashMap的初始過程 :在並發環境下使用HashMap
而沒有做同步,可能會引起死循環,關於這一點,sun的官方網站上已有闡述,這並非是bug。
HashMap的數據結構 :HashMap主要是用數組來存儲數據的,我們都知道它會對key進行哈希運算,哈系運算會有重復的哈希值,對於哈希值的沖突,HashMap採用鏈表來解決的。在HashMap里有這樣的一句屬性聲明:
transient Entry[]
table;
因此hashmap可以在andriod中用來存儲數據。
『伍』 hashmap底層實現原理
hashmap底層實現原理是SortedMap介面能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。
如果使用排序的映射,建議使用TreeMap。在使用TreeMap時,key必須實現Comparable介面或者在構造TreeMap傳入自定義的Comparator,否則會在運行時拋出java.lang.ClassCastException類型的異常。
Hashtable是遺留類,很多映射的常用功能與HashMap類似,不同的是它承自Dictionary類,並且是線程安全的,任一時間只有一個線程能寫Hashtable
從結構實現來講,HashMap是:數組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實現的。
(5)hashmap的存儲結構擴展閱讀
從源碼可知,HashMap類中有一個非常重要的欄位,就是 Node[] table,即哈希桶數組。Node是HashMap的一個內部類,實現了Map.Entry介面,本質是就是一個映射(鍵值對),除了K,V,還包含hash和next。
HashMap就是使用哈希表來存儲的。哈希表為解決沖突,採用鏈地址法來解決問題,鏈地址法,簡單來說,就是數組加鏈表的結合。在每個數組元素上都一個鏈表結構,當數據被Hash後,得到數組下標,把數據放在對應下標元素的鏈表上。
如果哈希桶數組很大,即使較差的Hash演算法也會比較分散,如果哈希桶數組數組很小,即使好的Hash演算法也會出現較多碰撞,所以就需要在空間成本和時間成本之間權衡,其實就是在根據實際情況確定哈希桶數組的大小,並在此基礎上設計好的hash演算法減少Hash碰撞。
『陸』 HashMap如何存儲數據的
對key進行hash,未發生碰撞,直接存儲,發生碰撞,碰撞數小於8,鏈表存儲,大於8,紅黑樹存儲。
參考:
飛升之路 Java學習筆記-HashMap原理
『柒』 HashMap是什麼東西
HashMap,中文名哈希映射,HashMap是一個用於存儲Key-Value鍵值對的集合,每一個鍵值對也叫做Entry。這些個鍵值對(Entry)分散存儲在一個數組當中,這個數組就是HashMap的主幹。HashMap數組每一個元素的初始值都是Null。
HashMap是基於哈希表的 Map 介面的實現。此實現提供所有可選的映射操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恆久不變。
(7)hashmap的存儲結構擴展閱讀:
因為HashMap的長度是有限的,當插入的Entry越來越多時,再完美的Hash函數也難免會出現index沖突的情況。
HashMap數組的每一個元素不止是一個Entry對象,也是一個鏈表的頭節點。每一個Entry對象通過Next指針指向它的下一個Entry節點。當新來的Entry映射到沖突的數組位置時,只需要插入到對應的鏈表即可。
『捌』 Java中HashMap和TreeMap的區別深入理解
HashMap底層是用數組做的,TreeMap是基於樹做的
這么做的結果就是HashMap的數據在不停的添加的時候效率會比較低,而對於查找的效率是比較快的,TreeMap對於添加的效率是比較高的但是對於查找的效率要相對比較低一些
這里簡單從底層說一下,我就不從具體的實現上說,只從數據結構和大致的原理上來補充一下我的答案。
HashMap這個類在存儲的時候,首先根據key來計算機將要存儲的key-value映射對存儲在數組的什麼位置上,當計算出位置後就把這個映射對存儲到這個位置上。當讀取的時候,首先根據key來計算出一個位置來,到數組的相應的位置上去讀取數據,如果沒有數據,則表示此Map中不存在該映射對,若存在則直接返回。說到這里就可以解釋一下為什麼對於不停地存儲的效率相對比較低了,首先在初始化的時候對於數組的長度給了一個初始的長度,當往這裡面添加數據達到一定的程度的時候就沒法繼續添加數據了,繼續添加數據的沖突就會增大,或者沒法添加數據(這里有一個衡量的量就是裝填因子,是指這個數組中的添加的數據的個數和數組長度的比值,在java中比較合理的裝填因子數是0.75),當數據添加到這個程度的時候不能不讓用戶繼續添加數據吧,總得解決繼續添加數據的問題啊,於是提出了解決方案,即開一個更大的數組,把當前上的每一個數據重新在更大的數組上計算位置,並把數據復制過去,這樣完成的數組的擴大,看完這個我們知道,這個過程是很耗時的,所以說對於不停的存儲數據時效率是比較低的。這里有沒有一個稍微好一點的解決方案或者說不需要進行數組的擴大嗎,我們能不能一開始在初始化的時候就把數組的空間開辟的足夠大,這樣就不用在存儲的過程進行復制了,可以嗎,答案是肯定的,java給我們提供了這個在初始化的時候的方式。但是,也是有問題的那就是我們的數據不夠多,就會造成空間的浪費。有沒有一個速度即快又不浪費空間的方式呢,解決方案也有一個,那就是在開始的時候我們就能很好的預測數據的規模,這樣我們在開始的時候按照相應的規模進行初始化,這樣就很好了,實際中我們是不能很好的預測這個規模的。於是對於這種情況提出了下一個解決方案TreeMap。
TreeMap是一個基於樹的存儲結構,學過數據結構的應該知道,樹的實現方式是基於指針實現的,在Java中是用引用模擬實現的,這里大家都知道,其實樹的讀取效率並不低,這里是相對於數組的順序查找來說的,但是與HashMap的查找方式相比就有了差距,HashMap是上來先問你在哪,直接就去取數據了,TreeMap需要遍歷,也就是需要挨個詢問你是我要的東西嗎,對比一下,是就返回,不是就繼續查找,於是查找的效率就低了,但是它解決了HashMap數組擴大的時候的效率問題,就是新添加的數據可以往裡面添加,不會出現復制的情況,這里就是由於模擬的指針的緣故實現的。
其實從總體來說這兩個各有利弊,我們在使用的時候需要根據實際的需要來選擇相應的類。
『玖』 關於C++中的哈希表
構
{int elem[MAXSIZE]; //數據元素體
HAVEORNOT elemflag[MAXSIZE]; //元素狀態標志,沒有記錄、有記錄、有過記錄但已被刪除
int count; //哈希表中當前元素的個數
}HashTable;
BOOL DeleteHash(HashTable &H,Record e)
{//在查找成功時刪除待刪元素e,並返回True,否則返回False
int p;
if(!SearchHash(H,e.keynum,p)) //表中不存在待刪元素
return False;
else
{H.elemflag[p]=DELKEY; //設置標志為DELKEY,表明該元素已被刪除
H.count--; //哈希表當前長度減一
return True;
}
}
BOOL SearchHash(HashTable H,int k,int &p)
{//在開放定址哈希表H中查找關鍵字為k的數據元素,若查找成功,以p指示
//待查數據元素在表中的位置,並返回True;否則,以p指示插入位置,並
//返回False
int p1;
p1=p=Hash(k); //求得哈希地址
while(H.elemflag[p]==HAVEKEY&&k!=H.elem[p])
//該位置中填有記錄並且關鍵字不相等
{p++; //沖突處理方法:線性探測再散列
if(p>=MAXSIZE) p=p%MAXSIZE; //循環搜索
if(p==p1) return False; //整個表已搜索完,沒有找到待查元素
}
if(k==H.elem[p]&&H.elemflag[p]==HAVEKEY) //查找成功,p指示待查元素位置
return True;
else return False; //查找不成功
}
『拾』 畫出hashmap數據結構圖,怎麼將hashmap變成線程安全
結構體:
typedefstruct_node{
void*key;
void*val;
struct_node*next;
}hashnode;
hashnode代表一個存儲節點,包含了指向其key域的指針、一個指向其val域的指針、一個作為hash沖突處理的鏈表指針。
實際使用時, 需要定義一個頭節點,由於hasmap一般是設定一個桶的大小,比如4096,那麼你需要定義一個4096個元素的數組,數組的每一個元素可以指向一個hashnode節點,因此,這個數組的定義應該是 hashnode* head[4096]
插入時,根據傳入的key算一個hash值,這個hash值由你指定的一個hash_function計算出來,然後插入到head桶中的一個位置
線程安全只需要在Insert操作和get操作時加一個讀寫鎖即可