半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法
Posted 码上猿梦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法相关的知识,希望对你有一定的参考价值。
我说的半夜, 并不是真正的半夜, 指的是在我一个人的时候, 我会去思考一些奇怪的问题.
这次思考的如题所示, 为什么重写 equals() 方法时, 强烈建议重写 hashCode() 方法, 这个答案, 应该大多数人都知道, 是为了减少 equals() 方法的调用, 只有当两个对象的 hashCode 相等时, 才会去调用 equals()方法去判断两个对象是否相等, 减少了equals()的调用, 提高了效率 .
话是这么说, 的确, 可以减少很多次的 equals()方法的调用, 但是不也是调用了 hashCode() 方法吗? 怎么就提高了效率了呢 ?
先说下什么情况下会重写 equals()方法, 一般情况, 实体类都需要根据自身的字段来实现 equals()方法, 在学习集合的时候, 一个是 Set 集合, 一个是 Map集合, 我对这两个集合的理解就是, 他俩是同母异父, 来的根源是一样的, 只是表现的不一样, 在存储自定义的实体类时, 为了保证存储的实体类不重复, 这也是 Set, Map的特性了, 比如需要存储两个人, 谁能证明两个人不同呢? 有两种方式证明 : 第一种是他们自己就具备证明的方法 ( 也就是Person类实现了Comparable接口 ),
第二种方式 : 派出所的人现场开证明 ( 传入比较器对象 ) , 好像扯远了, 和标题不一致了 .
我的记忆有点混乱了, 以为 compareTo() 方法需要使用到 equals()方法, 看了源码, 原来不需要, 罪过罪过,
源码放上来, 以防以后忘记 :
/* 字符串的比较的方法, 将字符串转换为char数组, 以为char是基本类型, 可以使用等号进行判断 */ public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }回忆一下, 原来是集合的 contains()方法依赖 equals()方法,
调用方法的数量是一致的, 效率的提高, 那么效率就在方法中了, 我直接拿 String类的源码来解释,
以上是关于半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法的主要内容,如果未能解决你的问题,请参考以下文章
重写 Equals 方法时是不是需要重写 == 和 != 运算符? (。网)
java中重写Object类的equals方法为啥要重写hashcode方法?不重写可以吗?
总结,为什么要重写hashset的hashcode()和equals()?
java中为什么重写equals时必须重写hashCode方法?