查看原文
其他

蔚来一面:用Object做hashMap的Key时需要做什么?

程序猿DD 2021-11-13

作者 | petterp

来源 | https://blog.csdn.net/petterp/article/details/89043847

先来说一下hashcode()和equals方法吧。

hashcode()

  1. hashCode 的存在主要用于查找的快捷性,如 Hashtable, HashMap 等,hashCode 是用来在三列存储结构中确定对象的存储地址的。
  2. 如果两个对象相同,就是适用于 euqals(java.lang.Object) 方法,那么这两个对象的 hashCode一定相同。
  3. 如果对象的euqals 方法被重写,那么对象的 hashCode 也尽量重写,并且产生 hashCode 使用的对象,一定要和 equals 方法中使用的一致,否则就会违反上面提到的第二点。
  4. 两个对象的 hashCode 相同,并不一定表示这两个对象就相同,也就是不一定适用于equals() 方法,只能够说明这两个对象在三列存储结构中,如 Hashtable.,他们存在同一个篮子里。以上话以前摘录自一篇博客,讲的非常好。

equals(Object obj)

  1. 如果一个类没有重写 equals(Object obj)方法,则等价于通过 == 比较两个对象,即比较的是对象在内存中的空间地址是否相等。
  2. 如果重写了equals(Object ibj)方法,则根据重写的方法内容去比较相等,返回 true 则相等,false 则不相等。

我用一个简单的demo来举个例子吧.

public class MyClass {
 public static void main(String[] args) {
     HashSet books=new HashSet();
     books.add(new A());
     books.add(new A());
     books.add(new B());
     books.add(new B());
     books.add(new C());
     books.add(new C());
     System.out.println(books);
 }
}
class A{
 //类A的 equals 方法总是返回true,但没有重写其hashCode() 方法
 @Override
 public boolean equals(Object o) {
     return true;
 }
}
class B{
 //类B 的hashCode() 方法总是返回1,但没有重写其equals()方法
 @Override
 public int hashCode() {
     return 1;
 }
}
class C{
 public int hashCode(){
     return 2;
 }

 @Override
 public boolean equals(Object o) {
     return true;
 }
}

结果

  1. 即使两个A 对象通过 equals() 比较返回true,但HashSet 依然把他们当成 两个对象,即使两个 B 对象 的hashCode() 返回值相同,但HashSet 依然把他们当成两个对象。
  2. 即也就是,当把一个对象放入HashSet 中时,如果需要重写该对象对应类的 equals() 方法,则也应该重写其 hashCode() 方法。规则是:如果两个对象通过 equals() 方法比较返回true,这两个对象的 hashCode 值也应该相同。
  3. 如果两个对象通过euqals() 方法比较返回true,但这两个对象的 hashCode() 方法返回不同的hashCode 值时,这将导致HashSet 会把这两个对象保存在 Hash 表的不同位置,从而使两个对象都可以添加成功,这就与 Set 集合的规则冲突了。
  4. 如果两个对象的 hashCode() 方法返回的 hasCode 值相同,但他们通过 equals() 方法比较返回false 时将更麻烦:因为两个对象的hashCode 值相同,HashSet 将试图 把它们保存在同一个位置,但又不行(否则将只剩下一个对象),所以实际上会在这个位置用链式结构来保存多个对象;而HashSet 访问集合元素时也是根据元素的 hashCode 值来快速定位的,如果 hashSet 中两个以上的元素具有相同的 HashCode 值时,将会导致性能下降。

用Object做hashMap的Key时需要做什么?

用自定义类作为key,必须重写equals()和hashCode()方法。

自定义类中的equals() 和 hashCode()都继承自Object类。


往期推荐

摊牌了,这些全是假的!埋了4个月的彩蛋都没被发现...

Stack Overflow 最火的一段代码竟然有 Bug...

居然有人提问“国家何时整治程序员的高薪现象”?

为什么不推荐使用 stop、suspend 方法中断线程?

阿里6000人发布联合倡议书:杜绝涉黄游戏和丑陋酒桌文化,HR不唯上、应更向人看!



喜欢本文欢迎转发,关注我订阅更多精彩

关注我回复「加群」,加入Spring技术交流群

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存