1. scala的map存儲散列演算法是字典順序嗎
不是,那個效率太低了
一、 使用 拉鏈式存儲
這個以 Java 中的 HashMap 為例進行講解。 HashMap 的內部有個數組 Entry[] table, 這個數組就是存放數據的。
Entry 類的定義大致是 :
class Entry {
Object key
Object value
Entry next;
}
所以, Entry[] table 的每個元素都是一個鏈表,即 HashMap 的內部存儲是 數組 + 鏈表,即拉鏈式存儲。
當往 HaspMap 中 put(key, value) 數據時,先進行 key.hashCode() & (table.length() - 1) ,得到一個小於 table.length() 的值, 稱為 index, 則這個新的 Entry 就屬於 table[index] 這個鏈表了 ( 如果鏈表還不存在,則把這個新的 Entry 作為鏈表的頭部了 ); 然後開始從前往後遍歷 table[index] 這個鏈表,如果 key.equals( entry.key ), 那麼表示這個 key 已經有了舊值,則替換 value 的值即可;
否則,把這個新的 Entry 插入到 table[index] 鏈表的最前面.
以上就是 HashMap 的存儲方式介紹了, 而且可以知道,作為 HashMap 的 Key, 它的 hashCode() 和 equals() 方法都被使用了
二、數組存儲
1.分散的數組存儲
這個以 ThreadLocal 和 ThreadLocal.Values 類為例進行講解。 Values 類裡面有兩個變數, Object[] table, 和 mask , table 就是存儲數據的數組了,table 的長度是 2 的倍數 , mask 的值就是 table.length - 1 ; 這一點和 HashMap 的內部存儲很像。 不過 table 中的每個元素就不是鏈表了。
當往 Values 中進行 put(key, value) 時,先進行 key.hashCode & mask ,得到一個小於 table.length 的值,稱為 index (與上面的 HashMap 好像,哈哈), 然後去檢查 table[index] 的值,如果不存在,則在 table[index] 處放入 key, table[index + 1] 處放入 value; 如果已經存在了,且 key.equals( oldKey ) 不成立,即發生了沖突,那麼 index = index + 2 ( 此處是 + 2,因為 key ,value 兩個是挨著放的,一個元素占倆坑 ) ; 往下一地方找找,如果再沖突,再找,直到找到一個可插入的地方,把 table[index] = key, table[index + 1] = value;
有兩處需要注意:
key.hashCode() 必須是 2 的倍數, 否則 index 的值有可能為奇數,如此就可能發生沖突了. 可參考 ThreadLocal.hash 這個成員變數
table 內部的數據是分散著存儲的.
2.連續的數組存儲
這個以 Android 中新增的 ArrayMap 為例進行分析( 據說沒 ArrayMap 是用來替換 HashMap 的哈 ), ArrayMap 中有兩個主要變數, int[] mHashes, Object[] mArrays.
mHashes 主要是存放 key 的 hash 值的, mArrays 是用來存放數據的,它也是奇數存放 key ,偶數存放 value , key 和 value 順序排列( 這個和 TheadLocal.value 中的 table 存儲方式很像 )。 mArrays 的長度是 mHashes 的 2 倍,畢竟 mArrays 是 key, value 都要存嘛~
mHashes 中存放 key 的 hash 值,是從小到大排列的,如果有多個 key 的 hash 值有一樣的,那麼就挨著排列
當往 ArrayMap 中進行 put(key, value) 時,先 int hash = key.hashCode, 然後通過二分查找在 mHashes 中查找 hash 的位置( 如果裡面有,就返回,如果無,就先找到最接近的位置,然後進行取反操作並返回 ) index,如果 index > 0 ,那麼再去 mArrays 中 2 * index 處獲取 key 值,比對兩個 key 是否 equals(), 如果不相等,那麼再分別向上、向下查找附近相同 hash 值的 key ,看是否有 equals() 的 key, 若有,則替換,若無,則插入; 如果 index < 0 ,表示之前沒有相等 hash 的 key 插入過,那麼 index = ~index( 再次取反,就是個正數了,代辦要插入的位置), 再在 mHashes 的 index 處插入 hash, 在 mArrays 的 2 * index 處插入 key, 在 (2 * index ) + 1 處,插入 value .
注意:
mHashes 和 mArrays 在插入新數據時,都需要把插入位置後面的數據向後移動一個單位,這個對於頻繁插入、刪除的動作來說消耗比較大.
key 的 hash 大小決定了插入的順序
3.以數字為 key 的數組存儲
這類的 map 比較特殊,key 是數字類型。 這個以 Android 中新增的 SparseArray 進行分析。 SparseArray 中有兩個主要變數, int[] mKeys 和 Object[] mValues , mKeys 是存放 key 的,是個有序數組,從小到大排列; mValues 是與 mKeys 一一對應的 value 值集合. mKeys 和 mValues 的長度是相等的。
當往 SparseArray 中 put(key, value) 時,先用二分查找在 mKeys 中查找 key 所在的位置 (如果找到,返回; 如果沒有找到,則找到它應該插入的位置,取反並返回) ,記為 index, index > 0 ,則直接在 mValues[index] 處替換 value; 如果 index < 0 ,則 index = ~index, 即取反, 然後在 mKeys 的 index 處插入 key , 在 mValues[index] 處插入 value ,之前的數據自 index 處後移一個單位。
注意:
mKeys 和 mArrays 的數據插入時,都是要進行數據移動的,對頻繁插入、刪除的 map 來說消耗很大.
最後了,對它們的優缺點做些對比。
HashMap : 內存佔用較大,增、刪的效率較高,改、查的效率一般
ThreadLocal.Values : 內存佔用一般,當數據量比較小時,增刪改查的效率高;數據量大時,增刪改查效率一般
ArrayMap: 內存佔用較小,改、查的效率高,增、刪的效率較低
SparseArray : 內存佔用較小,改、查的效率高,增、刪的效率低,且主鍵是數字
最後,我們不評判哪種存儲方式好,一切都要以實際情況實際分析,找出最符合的那種存儲,哈哈~
2. python字典是否有序
默認情況下Python的字典輸出順序是按照鍵的創建順序。
字典的無序是指,不能人為重新排序。
比如說你按鍵值1,2,3,4的順序創建的字典,只能由解析器按創建順序,還是1,2,3,4的輸出。
你無法控制它按照4,3,2,1的順序輸出,你也無法做到1,3,2,4的順序。
而且這個輸出順序是也不是能真正按照創建順序可以控的。
這裡面有兩個影響因素:
(1)鍵值的哈希碰撞,hash(key1) == hash(key2)時,向字典里連續添加的這個兩個鍵的順序是不可以控制的,也是無法做到連續的,後來的鍵會按演算法調整到其它位置。
(2)字典空間擴容,當鍵的數量超過字典默認開的空間時,字典會做空間擴容,擴容後的鍵順和創建順序就會發生變化,不受人為控制。
3. Python中的字典是有順序的嗎
序列類型用有序的數字鍵做索引將數據以數組的形式存儲。一般索引值與所存儲的數據毫無關系。還可以用另一種方式來存儲數據:基於
某種相關之,比如說一個字元串。
哈希表的演算法是獲取鍵,對鍵執行一個叫做哈希函數的操作,並根據計算的結果,選擇在數據結構的某個地址中存儲你的值。任何一個值
的地址皆取決與它的鍵。正因為這種隨意性,哈希表中的值是沒有順序的。你擁有一個無序的數據集。
你所能獲得的有序集合只能是字典中的鍵的集合或者值的集合。由於字典本身是哈希的,所以是無序的。
python學習網,免費的python學習網站,歡迎在線學習!
4. ios 字典循環存儲後順序變了嗎
字典,不存在順序吧
5. 字典可以排序嗎
可以。
字典本身沒有順序概念,但是總是在某些時候,但是我們常常需要對字典進行排序,通常是按照key值排序。或者用sorted函數的key=參數排序,當然也有按照value排序的。
6. 新華字典上的字是按什麼順序排列的
《新華字典》全書按音序排列。
《新華字典》另附《部首檢字表》。書中採用的部首與一般字典基本相同,但略有改動,共有189部。
如舊日字典的肉部、艸部、高部、鼓部、 齊部、龜部等都並省,而有些舊日字典根據《說文解字》、篆書的寫法不分的,這本字典里都按楷書的寫法分為兩部,如「刀」與「刂」,「火」與「灬」,「心」與「忄「,「水」 與「氵」,便於查檢。這種辦法在中國字典中是前所未有的。
所收單字有8500個左右,在單字訓解之下連帶加出的復音詞和片語有3200多個。復音詞和片語都加有標志,這樣就兼有簡單詞典之用。
(6)字典是順序存儲嗎擴展閱讀
《新華字典》最早的名字叫《伍記小字典》,但未能編纂完成。自1953年,開始重編,其凡例完全採用《伍記小字典》。從1953年開始出版,經過反復修訂,但是以1957年商務印書館出版的《新華字典》作為第一版。
原由新華辭書社編寫,1956年並入中國科學院語言研究所(現中國社會科學院語言研究所)詞典編輯室。《新華字典》由商務印書館出版,歷經幾代上百名專家學者十餘次大規模的修訂,重印200多次,成為迄今為止世界出版史上最高發行量的字典。
《新華字典》是中國第一本按漢語拼音音序排列的小型字典。1953年新華辭書社編,主編者為語言文字學家魏建功(1901—1980)。1953年由人民教育出版社印行第一版,按注音字母順序排列;以後續有修訂,改用漢語拼音字母順序,轉由商務印書館重排出版。
7. 順序存儲結構和鏈式存儲結構優缺點
順序存儲結構和鏈式存儲結構的區別
鏈表存儲結構的內存地址不一定是連續的,但順序存儲結構的內存地址一定是連續的;
鏈式存儲適用於在較頻繁地插入、刪除、更新元素時,而順序存儲結構適用於頻繁查詢時使用。
順序存儲結構和鏈式存儲結構的優缺點:
空間上
順序比鏈式節約空間。是因為鏈式結構每一個節點都有一個指針存儲域。
存儲操作上:
順序支持隨機存取,方便操作
插入和刪除上:
鏈式的要比順序的方便(因為插入的話順序表也很方便,問題是順序表的插入要執行更大的空間復雜度,包括一個從表頭索引以及索引後的元素後移,而鏈表是索引後,插入就完成了)
例如:當你在字典中查詢一個字母j的時候,你可以選擇兩種方式,第一,順序查詢,從第一頁依次查找直到查詢到j。第二,索引查詢,從字典的索引中,直接查出j的頁數,直接找頁數,或許是比順序查詢最快的。
8. Python中的字典是什麼
字典(Dictionary)
字典也是Python語言中經常使用的一種數據類型。跟列表類似,字典是另外一種可存儲任意類型的數據,並且字典儲存的數據也是可以修改的。
不同於列表的是,字典每個基本元素都包括兩個部分:鍵(key) 和 鍵對應的值(value)。
- d = {"key1" : 1, "key2" : "hi", "key3":[]}
在字典中,鍵的內容是不可重復的。鍵為不可變數據類型,值可以是任何數據類型。在這里,鍵只支持字元串類型。
字典最大的優勢就是能在海量數據下利用「鍵」快速查找出想要的值,當有很多數據需要存儲的時候,我們給每個值都打個標簽,也就是「鍵」;想要調用這個值時,字典能夠利用這個標簽快速幫我們找到它。但是如果標簽重復了,字典不知道哪個值才是對的,就會報錯哦~
列表是根據排序來記錄每項的值,但是字典是沒有順序的,所以同一字典,每次列印出的排序可能是不同的。「鍵」才是調用字典的關鍵元素。
字典是基礎的數據類型,所以變數也可以被賦值為字典。
鍵和值之間用冒號(:)分割,每對元素之間用逗號(,)分割,整個字典的數據在大括弧{}中,格式如下所示: