arrayMap
主要數據結構:hash數組和數據數組
描述:有2個數組,一個存放key.hashcode(),另一個實際存放數據的數組 存放key和value(偶下表放key,+1下標放value,所以該數組大小至少為hash數組的2倍),hash數組存放hash值為有序存放,查找的時候根據key的 hash用二分法查找,找到的下標作為返回值,該下標*2 = 實際存放數據下標的key 的下標, +1為value下標
hash碰撞:keyhash一樣就認為是同一個對象,直接替換value
enumMap
主要數據結構:數組
描述:本質就是一個數據,key為 Enum類型,獲取 int order() 為下標,數組內容存放value
hash碰撞:不用key的hash做索引,所以只要order一樣,則認為key是一樣的
hashMap
主要數據結構:數組+下標哈希
描述:有 Node<K,V> table[] 數組, 下標作為hash表 keyHash & (table.length - 1) ,按位與做了hash散列的映射,獲得的掩碼值作為下標, 當table 的數據類型是 TreeNode 時,一般用在LinkdHashMap 中。
hash碰撞:
1.拉鏈法(鏈表)
hash一樣時,還要判斷 value , == 和 equals() 都成立則認為是同一個對象,否則認為是hash碰撞,在同一個hash桶內,用單向鏈表鏈接相同hash的元素,並從第一個元素開始遍歷鏈表,依次用 == equals() 判斷是否是同一個value對象,若是則替換value,否則直到鏈表尾都不存在匹配上的對象,則通過可 覆寫 函數newNode()新建一個node,接入鏈表尾部。
2.紅黑樹
identityHashMap
主要數據結構:數組+下標哈希
描述:用Object[] table; 做存儲,下標為hash表(和hashmap類似),不同是key的hashcode為 h=System.identityHashCode() 獲得,並且hash運算為 ((h << 1) - (h << 8)) & (length - 1) ,只有與table的length-1 做位與相同 (Multiply by -127, and left-shift to use least bit as part of hash 沒理解,)根據key和len算出的下標,存放key對象, 該下標+1 處,存放value對象。
hash碰撞:再次散列:依序往后順延一個存儲位(基於上次index的值+2),如果key對象是同一個 (==),則認為是同一個元素,否則認為只是不同key對象,產生的hash碰撞。
LinkedHashMap
主要數據結構:用雙向鏈表存儲
描述:通過 覆寫 父類獲取Node 的函數 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) ,來返回 LinkedHashMapEntry 類型的Node ,該Node 多了 前,后,節點的指針,作為雙向鏈表節點使用。LinkedHashMap還多了 head,tail 雙向鏈表的節點。
在刪除時,覆寫 afterNodeRemove(Node<K,V> e) 方法,將刪除的節點 從雙向鏈表中剔除(根據before和after),最后刷新head 和 tail
linkedhashmap是有序的,在使用迭代器的時候可以看到遍歷順序和插入順序相同,這是和hashmap是無序的(迭代順序依照keyhash的數值大小),linkedhashmap保持有序的原因是,插入數據時,利用LinkedHashMapEntry的 before 引用到tail,所以遍歷時,根據從head 節點的 after 一直到 tail 節點,便可以還原出和插入順序一致的遍歷順序。?
LinkedHashMap有序,可分為插入順序和訪問順序兩種。如果是訪問順序,那put和get操作已存在的Entry時,都會把Entry移動到雙向鏈表的表尾(其實是先刪除再插入)
hash碰撞:因繼承hashMap,所以和hashMap一致。(拉鏈法)
TreeMap
主要數據結構:紅黑樹
描述:用 TreeMapEntry<K,V> root; 存儲樹的根節點,節點主要記錄,左右父節點,顏色,key,value。插入時根據比較器(傳入key的值)返回的相對大小,從樹根向下查找相同節點,只要比較器認為key相同則TreeMap認為元素相同,如果沒有找到相同元素,則在最后遍歷到位置的樹的末尾插入新節點,然后根據2-3樹的性質上浮超過-3元素(一個節點中有超過2個子節點的情況)的節點的中間子節點,並通過左右旋轉(AVL樹相關算法)修復樹最大最小樹深度不超過1的特性。
hash碰撞:比較器認為key相同則元素相同,直接替換。不存在hash的問題。