HashMap

1.HashMap的概述

  • HashMap 是基于哈希表的 Map 接口的非同步实现。
  • 这个实现提供所有可选的映射操作, 并允许使用 null 值和 null 键。
  • Hashmap实际上是一个数组和链表的结合体(在数据结构中,一般称之为“链表散列“)。

2.HashMap的数据结构

HashMap 底层就是一个数组结构,数组中的每一项又是一个链表,当新建一个 HashMap 的时候,就会初始化一个数组
横排表示数组,纵排表示数组元素【实际上是一个链表】
HashMap中的key-value都是存储在Entry中的

在这里插入图片描述

3.equals方法与hashcode的重写

  • Object.equals方法:如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
  • HashCode方法:hashCode方法实际上返回的就是对象存储的物理地址,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次 。
  • 一个HashMap方法的调用:hashmap 找value的时候一定是通过key转化为hashcode去找的,hashmap 中的元素通过hashcode找到元素的物理地址,查看这个物理地址是否拥有数值,如果有,那就用equles方法去比较。如果相等,这个数值就不存了,如果不相等,就散列到其他的地址。
    Hashmap的key可以是任何类型的对象,例如User这种对象,为了保证两个具有相同属性的user的hashcode相同,我们就需要改写hashcode方法,比方把hashcode值的计算与User对象的id关联起来,那么只要user对象拥有相同id,那么他们的hashcode也能保持一致了,这样就可以找到在hashmap数组中的位置了。如果这个位置上有多个元素,还需要用key的equals方法在对应位置的链表中找到需要的元素,所以只改写了hashcode方法是不够的,equals方法也是需要改写滴~当然啦,按正常思维逻辑,equals方法一般都会根据实际的业务内容来定义,例如根据user对象的id来判断两个user是否相等。
    在改写equals方法的时候,需要满足以下三点:
    (1) 自反性:就是说a.equals(a)必须为true。
    (2) 对称性:就是说a.equals(b)=true的话,b.equals(a)也必须为true。
    (3) 传递性:就是说a.equals(b)=true,并且b.equals©=true的话,a.equals©也必须为true。
    通过改写key对象的equals和hashcode方法,我们可以将任意的业务对象作为map的key(前提是你确实有这样的需要)。

4.HashMap的一些点

  • HashMap实现不同步,线程不安全。
  • HashMap中的key-value都是存储在Entry中的。
  • HashMap的实例有俩个参数影响其性能: “初始容量” 和 装载因子。
  • HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
  • HashMap是采用拉链法解决哈希冲突的。
  • HashMap在并发环境下使用中最为典型的一个问题,就是在HashMap进行扩容重哈希时导致Entry链形成环。一旦Entry链中有环,势必会导致在同一个桶中进行插入、查询、删除等操作时陷入死循环
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值