用自定义类型作为HashMap或Hashtable的key

探讨HashMap存储机制,解析键值对添加流程,强调自定义Key时equals与hashCode方法的重要性,及设计不可变类的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap 和 Hashtable 时用来存放键值对的一种容器,不能存储重复的键。若有重复,则覆盖原来的映射关系。

HashMap添加元素的操作过程:

首先,调用key的hashCode( ) 方法生成一个 hash 值 h1,如果在HashMap中不存在,则直接将<key, value>添加到HashMap中;如果这个 h1 已经存在,则找出HashMap中所有hash值为 h1 的key,然后分别调用 key 的equals( )方法来判断添加的key与已经存在的key是否相同。如果equals( )返回true,那么会使用新的 value 覆盖原来的 value 值;如果返回 false ,说明新增加的 key 在HashMap中不存在,因此会在HashMap中建立新的映射关系。

当新增的key的hash值已经存在时,就会产生冲突(一般不同的key值也可能产生相同的hash值),解决冲突的方法有:开放地址法、再hash法、链地址法等。HashMap采用的是链地址法。

结论:

在使用自定义类作为HashMap的key时,需要注意一下几个问题:

(1)如果想根据对象的相关属性来自定义对象是否相等的逻辑,需要重写equals( )方法,一旦重写了equals( ) 方法,就必须重写 hashCode( ) 方法。

(2)当自定义类的多项作为 HashMap(Hashtable)的 key 时,最好把这个类设计成 不可变类(设计不可变类,见下面补充)。

(3)从HashMap的工作原理看,如果两个对象相等,那么这两个对象有着相同的hashCode值,反之不成立。

补充:如何设计不可变类

Java中如何设计不可变类:

  1. 不提供setter方法,setter方法用于修改属性和对象引用 
    这个原则阐述了在你类定义的所有可变属性中,不提供setter方法,setter方法意味着你能够改变这个属性的状态。必须阻止提供setter方法
  2. 所有的属性修饰添加private和final 
    这是另外一种增加不可变的方式,属性声明为private为了在类之外不能够被访问到,final修饰符为了让你不能随便的改变它们
  3. 不允许子类重写方法 
    最简单的方式声明类为final,final类不允许被重写
  4. 当属性中存在可变对象变量时,要特别留意 
    永远铭记你的对象变量,不是可变的就是不可变的(这句好像是废话。。),识别出来可变对象,对可变对象的内容进行copy,并创建一个新对象赋值给它,这样保证可变对象的不可变,通过直接copy对象内容的形式,保持数据不可变
  5. 来点优雅的,定义一个private的构造方法,通过 工厂方法构造对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AndyAtcsdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值