0
点赞
收藏
分享

微信扫一扫

【Java集合】重点Map

1 arrayMap

  主要数据结构:hash数组和数据数组

  描述:有2个数组,一个存放key.hashcode(),另一个实际存放数据的数组 存放key和value(偶下表放key,+1下标放value,所以该数组大小至少为hash数组的2倍),hash数组存放hash值为有序存放,查找的时候根据key的 hash用二分法查找,找到的下标作为返回值,该下标*2 = 实际存放数据下标的key 的下标, +1为value下标

  hash碰撞:keyhash一样就认为是同一个对象,直接替换value

 

2 enumMap

  主要数据结构:数组

  描述:本质就是一个数据,key为 Enum类型,获取 int order()  为下标,数组内容存放value

  hash碰撞:不用key的hash做索引,所以只要order一样,则认为key是一样的

 

3 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碰撞。

 

4 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一致。(拉链法)

 

5 TreeMap

  主要数据结构:红黑树

  描述:用 TreeMapEntry<K,V> root; 存储树的根节点,节点主要记录,左右父节点,颜色,key,value。插入时根据比较器(传入key的值)返回的相对大小,从树根向下查找相同节点,只要比较器认为key相同则TreeMap认为元素相同,如果没有找到相同元素,则在最后遍历到位置的树的末尾插入新节点,然后根据2-3树的性质上浮超过-3元素(一个节点中有超过2个子节点的情况)的节点的中间子节点,并通过左右旋转(AVL树相关算法)修复树最大最小树深度不超过1的特性。

  hash碰撞:比较器认为key相同则元素相同,直接替换。不存在hash的问题。

  


举报

相关推荐

0 条评论