初学者: 请非常通俗的解释:
我把HashCode理解为是大楼的本牌号,真实地址是经纬度。
经纬度不可变,但是大楼的门牌号却是可以变的。
现在请如上通俗的告诉我: 为什么我equals变,HashCode 也要变。
1.我目前知道的就是Object中的equals和HashCode都是最基本的,需要重写。
2. 还知道String类,equals通常是先比较地址,然后一个字符一个字符比较。
还有就是我想知道HashCode存在的意义是什么,不要说什么进程怕被扰乱,我看不懂
假定我现在有一个数组 A[] arr = new A[11],我想向其中存储一系列的A对象,我的要求是取的时候特别方便,不用循环,可以直接找到对象的位置,那应该怎么做呢~?
对于一个对象A a , 如果我可以通过某种固定的算法f得到一个值hashCode , 那么我就可以通过这样的方法把A放入数组:int index = hashCode % arr.length
通过这个算法得到一个索引,因为是模arr.length ,那么这个索引肯定是大于等于0小于arr.length 的,我可以把对象a放入数组arr[index]中,
这样如果我需要从数组中取出a,我就不用遍历数组去一个个找a在哪个位置,我只用再一次使用上面那个算法,算出索引,通过这个索引,我就可以直接拿到a了。
这就是hashCode存在的意义。
接下来说为什么重写了equals 还要重写 hashCode,假定现在有这样的场景
两个对象 A a 和 A b,在我们的场景中我们可能需要重写equals, 判定如果 a 的 属性 name 和 b 的属性 name相等,那我就认定a,b是相同的对象,在向数组 arr里存的时候,我就不能再存多个,只存一个。但是 我们是用hashCode()去计算a,b的位置,默认从Object继承来的hashCode是基于对象的ID实现的 , 也就是说可能这两个对象在我们重写了equals()之后认为是相同的对象,但是hashCode()却不一样,在向数组里存的时候,被判定为不同的对象存到不同的索引中去了,所以我们需要重写hashCode()方法,使得如果我们重写的equals()判定两个对象是相同对象的话,那他们的hashCode()也要返回相同的数值。
这里面说的很通俗,你看看吧
http://www.cnblogs.com/lulipro/p/5628750.html
你可以这样认为,一个对象的HashCode相当于它的内存地址(只能说等同),equals相当于它的描述。默认情况下,equals方法就是比较地址,你可以看Object类的源码。
其次我想说的是,需不需要重写不是必须的,只是针对具体的需求,比如说map当中的put方法就需要比较hashcode和equals,但是String的比较就只需要equals就好了。
另外一般的equals重写都会先比较地址,你想想看,如果地址相同,那么这两个对象一定是同一个对象呀,就像你现在站立的地方,不能除了你之外还有谁站立这吧。
String之所以比较字符,是因为String当中相等的用途就是内容一样。
http://blog.csdn.net/jiangwei0910410003/article/details/22739953
(1)为什么我equals变,HashCode 也要变。(重写了equals就要重写HashCode)
如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。,,就像答主所说,,明明两个门是“相等”的,门牌号却不一样有点矛盾。(这里的相等不是“==”这个相等。因为比较对象相等不能靠“==”)
(2)还有就是我想知道HashCode存在的意义是什么,
hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
(参考链接:http://blog.csdn.net/fenglibing/article/details/8905007)
最后:
楼上回答链接里的这两句话:
重写了euqls方法的对象必须同时重写hashCode()方法。
如果2个对象通过equals调用后返回是true,那么这个2个对象的hashCode方法也必须返回同样的int型散列码
如果2个对象通过equals返回false,他们的hashCode返回的值允许相同。(然而,程序员必须意识到,hashCode返回独一无二的散列码,会让存储这个对象的hashtables更好地工作。)
所谓的*一般自己定义的javabean中都需要重写hashcode和equals方法*的说法,目的是为了明确的**区分两个对象是否相等这个目的**。使用==
判断就是比较对象的地址是否相等,地址一致,则必然是一个对象,肯定相等;使用equals判断,这个可以自己定义这个bean中哪些元素相等就等同于二者相同,比如List.contains方法的结果就直接取决于equals方法,因为它是根据equals方法来判断两个对象是否相同,从而判断集合中是否包含该元素;而如果使用HashMap或者HashTable这些集合类的时候,就必须重写hashcode方法,因为它们会根据hashcode方法来判断是否包含该键值。
题主态度很强势啊,“我看不懂”,这个非常强势。。。
说正题。。。。
“为什么我equals变,HashCode 也要变”是什么意思?
未重写的情况下,同一个对象实例的HashCode是一样的,题主是不是对“对象实例”和“对象”混淆了?
这个问题比较复杂,我推荐你看一下我之前写的博客,我先简单说明一下:
hashCode的目的提高哈西算法的效率,可以帮助程序迅速的在庞大的内存中快速找到这个对象,例如在学校,在几千人中我要找到你,你的hashCode是你的班级,那我就可以迅速的从几千人当中缩小范围到几十人,HashCode就起到类似的作用。
如果重写了equals方法,而没有恰当的重写hashCode方法,就会影响查找这个对象的速度,程序的效率也就会降低,所以系统系统是推荐两个方法是同时重写,如果你任性不重写,系统也不会把你怎么的,但是对于追求性能的开发者来说,是一件很失败的事情。
http://blog.csdn.net/u011315960/article/details/73909962
http://blog.csdn.net/u011315960/article/details/74406947
http://blog.csdn.net/u011315960/article/details/74530973