黑马程序员技术交流社区

标题: 为什么要重写hashCode()方法 [打印本页]

作者: 瓶中人    时间: 2013-10-21 14:37
标题: 为什么要重写hashCode()方法
本帖最后由 瓶中人 于 2013-10-22 00:37 编辑

class Cat
{
        private String name;
        private int age;
        private double weight;
        private Color color;
        public Cat(String name , int age , double weight , Color color){
             this.name = name;
                 this.age = age;
                 this.weight = weight;
                 this.color = color;
        }
        public boolean equals(Object obj){
            if(this == obj){
                     return true;
                 }
                 if (obj == null)
                 {
                         return false;
                 }
                 if(this.getClass() != obj.getClass()){
                    return false;
                 }
                 Cat cat = (Cat)obj;
                 return name.equals(cat.name)&&(age == cat.age)&&(weight == cat.weight)&&(color.equals(cat.color));
        }
        public int hashCode(){
             return 7 * name.hashCode() + 11* new Integer(age).hashCode() + 13 * new Double(weight).hashCode() + 17 * color.hashCode();
        }
}
为什么比较对象是否相等要重写hashCode()方法呢,明明有重写equals()就可以说明问题了?
作者: ゞ心痛-τ._煩離    时间: 2013-10-21 15:23
因为equals比较得是两个对象,或者是两个对象的内容,假如两个对象相等那它们两个的hashcode也必须一样,因为hashcode是用对象的内部地址转换成一个整数的。其默认从Object继承来的hashCode是基于对象的ID实现的。如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样。这样,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值去查找他们的时候,则根本找不到。在java的集合中,判断两个对象是否相等的规则是:  


首先,判断两个对象的hashCode是否相等

如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等  
如果不相等,认为两个对象也不相等  
如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率

作者: cuilitang    时间: 2013-10-21 20:26
为了提高效率,先重写HashCode方法,去比较独享属性的HashCode值的和。
若是相同再取出每个对象的属性进行equals或者==比较。
这样速度是比直接把每个对象的属性拿出来进行比较速度是快的。

作者: 瓶中人    时间: 2013-10-24 01:11
ゞ心痛-τ._煩離 发表于 2013-10-21 15:23
因为equals比较得是两个对象,或者是两个对象的内容,假如两个对象相等那它们两个的hashcode也必须一样,因 ...

可以问一下,重写hashCode(),如public int hashCode(){
            return 11.name.hashCode() + 5* new Integer(age).hashCode() + 6*new Double(weight).hashCode() + 12* color.hashCode();
        }
为什么要乘以那些数字呢?
作者: ゞ心痛-τ._煩離    时间: 2013-10-24 19:20
瓶中人 发表于 2013-10-24 01:11
可以问一下,重写hashCode(),如public int hashCode(){
            return 11.name.hashCode() + 5* new Intege ...

如果你一个对象的age=3,weight=10而另一个对象的age=10,weight=3,其他一样的话,那么两者的hashcode还是一样,前面乘以数字就是为了保证每个对象的hashcode值唯一,乘以的数字可以使任意的,但不要一样……
作者: 瓶中人    时间: 2013-10-24 20:22
ゞ心痛-τ._煩離 发表于 2013-10-24 19:20
如果你一个对象的age=3,weight=10而另一个对象的age=10,weight=3,其他一样的话,那么两者的hashcode还 ...

谢谢,我脑子有点不会转弯!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2