集合类——Map和子实现类HashMap&HashTable

Map键值对 Key-Value

  1. Map集合体系的顶级接口
  2. 存储的是key-value数据(我们正在研究Map下的集合类的时候,关注点在key上)
  3. 有的子实现key是有序的,有的子实现key是无序的
  4. 子实现key是不允许重复的(重复的定义不一样)
  5. 有的子实现key允许存储null,有的子实现key不允许存储null

API

官方文档

voidclear()
          从此映射中移除所有映射关系(可选操作)。
 booleancontainsKey(Object key)
          如果此映射包含指定键的映射关系,则返回 true。
 booleancontainsValue(Object value)
          如果此映射将一个或多个键映射到指定值,则返回 true。
 Set<Map.Entry<K,V>>entrySet()
          返回此映射中包含的映射关系的 Set 视图。
 booleanequals(Object o)
          比较指定的对象与此映射是否相等。
 Vget(Object key)
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
 inthashCode()
          返回此映射的哈希码值。
 booleanisEmpty()
          如果此映射未包含键-值映射关系,则返回 true。
 Set<K>keySet()
          返回此映射中包含的键的 Set 视图。
 Vput(K key, V value)
          将指定的值与此映射中的指定键关联(可选操作)。
 voidputAll(Map<? extends K,? extends V> m)
          从指定映射中将所有映射关系复制到此映射中(可选操作)。
 Vremove(Object key)
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
 intsize()
          返回此映射中的键-值映射关系数。
 Collection<V>

values()
          返回此映射中包含的值的 Collection 视图。

解释

以上黄字红底的是在面试的时候必须要掌握的,不然真的凉凉

下面两个图描述的是前后端不分离和分离的两个模型

 

 HashMap 重点 面试必问

结构特点:数组+链表+红黑树

 

  1.  HashMap是Map接口的一个具体实现
  2. 哈希表,HashMap底层接口是数组+链表+红黑树(红黑树是jdk1.8版本后新加的结构)
  3. 数组的默认初始长度16(第一次添加元素产生长度为16) 数组扩容机制,扩容为原来的2倍-->数组长度必定2的幂值-->位运算
  4. HashMap存储Key是无序的
  5. HashMap不允许存储重复的key值(对于HashMap来说key的重复定义是啥)
  6. HashMap允许存储null建
  7. HashMap线程不安全
  8. HashMap的加载因子是0.75,可以在构造方法中传入因子,建议在0.5-1之间,不要太荒唐
  9. HashMap中hash值的计算:Hash = (h = key.hashCode())^(h >>> 16);
  10. 如果我们在构造方法中给定一个长度,那么hashmap会创建一个底层数组长度大于等于给定值的最小的2的幂值的一个数组                                                                             (ArrayDeque是产生大于,而非大于等于)
  11. 主观上 我们希望每个key都可以散列到数组的不同位置,实际上是没有办法保证的。实际上在我们hash值取下标(和数组长度取模)的过程中,只有hash值的低位才会有用,也就意味着,我们最终在hashmap数组上所散列的位置依赖于hash的低位。
  12. 我们存储到数组位置的key-value数据,实际上数组存储的是一个Node类型的结点,
  13. 45
  14. 也就意味着,如果我们用一个普通的java对象来充当key的时候,我们希望比较的是这个对象里面的存储的内容,那么要根据这个对象里面的参数重写hashCode和equals方法(仅重写equals方法是不行的) 如果两个
  15. 如果要存储的key-value数据,这个key值已经在HashMap上存在,那么我们会用新的这份key-value数据的value来覆盖已经存储到HashMap上的(已经存储重复的),key-value的value值(key值不会覆盖)
  16. 在HashMap存储中,如果多个key-value数据散列到同一个下标位置,key值也不重复,那么这个位置就会构建出一个单链表,如果单链表过长,那么这个链表要转化为红黑树。所谓的过长,是指链表长度超过8达到9的时候 这里有个勘误,很多地方都说>=8的时候,就会转化为红黑树。算上新添加的结点 
  17. 在HashMap中,某一个数组位置链表长度超过8达到9的时候,一定会转化为红黑树吗为什么这样?因为考虑到随便就转化红黑树的话,效率会变低。扩容,key-value的hash是不变的,hash来源于key的hasCode,数组长度遍历。取模变化结果->存储位置有可能变化
  18. 如果一个key-value数据原本在下标为x的位置,当发生扩容的时候,它只可能重新散列表的两个位置:因为数组长度是2的幂值
      原本的x位置
     X + 就长度的位置到这一步就行了,不想在往底层看了....
  19. 红黑树什么时候转化为链表?
    有两种情况会导致红黑树转化为链表:
    one:删除红黑树上的元素,如果链表刚转化为红黑树,那么这时候删除红黑树一个元素,并不会马上变回链表
    two:扩容的时候,会导致红黑树有可能转化回链表,扩容会把一个元素位置的数据拆成两个位置
  20. 存储到红黑树(特殊二叉搜索树)是要能比较大小,在
  21. 已经存储到HashMap中的key-value不要通过引用来修改key值,

寄语:希望给位看官宝贝儿们看源码不要过度解读,看的是核心逻辑

所以h >>> 16 位的原因是希望高位数也能参加到取模运算中来,以达到充分散列的效果(希望)

加载因子是数组(key-value数据)到一定容量的时候,就会扩容数组,避免链表和红黑树过多过长导致存储效率变低

扩容阈值=加载因子 * 数组长度

HashMap是怎么存储key-value数据的

  1. HashMap在存储一份key-value数据的时候,先把key取出来,计算
  2. key经过计算后,得到一个int类型的hash值
  3. 把这个经过计算的hash值和HashMap的数组长度取模,得到下标
  4. 如果这个下标位置,没有元素,把这份key-value数据,存到这个下标位置(存储的是一个结点类型,这个结点类型里面包含了key,value)
  5. 如果这个下标位置,已经存储了结点,判断key值和这个下标位置的这些已经存在的结点中的key值是否重复,如果重复不添加,如果不重复,添加到这个位置(链表的尾部)
  6. 如果链表过长,把链表转化为红黑树

注意:从单纯数学领域(当下),hash

Hash算法:

MD4

MD5

SHA1

SHA2

构造方法

可以去jdk开发手册上去看

HashMap判断key值重复的依据:根据hash值和equals方法来判断的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值