四、覆写equal()

四、覆写equal():
        四大特性:①自反性; 判断是否引用同一个对象;
                          ②对称性; A.equals(B)相等,B.equals(A)也相等;
                          ③传递性; A.equals(B)相等,B.equals(C)相等,那么A.equals(C)也相等;
                          ④一致性; 两对象不变的情况下,A.equals(B)一直相等或者一直都不相等;

        步骤:①使用==操作符检查 参数是否为同一个对象的引用;
                   ②使用instanceof操作符检查 参数是否为正确的类型;
                   ③把参数转换为正确的类型;  因为参数必须为Object类型,所以要强转;
                   ④对于该类中的每个关键域,检查参数中的域是否与该对象中对应的域相匹配;
                   ⑤审阅是否满足4大特性。
        
       注意:覆盖equals时总要覆盖hashCode;    HashMap、HashSet和Hashtable。
                  不要企图让equals方法过于智能;
                  不能将equals声明中的Object对象修改为其他的类型。

       问题一:为什么equals声明中的参数对象一定要为Object?
            原理:因为如果equals方法的参数不是Object类型的话,则属于是重载了Object.equals()。
                       所以当重载了Object.equals()时,遇到了继承的情况就不会调用同一个equals()了 。
            实例:
public class Test1 extends Test2 {
    public Test1 equals(Test1 test1) {
        System.out.println("haha");
        return null;
    }

    public static void main(String[] args) {
        Test1 test1 = new Test1();
        Test2 test2 = new Test2();
        test1.equals(test2);            //Object中的equals() ;
        test2.equals(test1);            //Object中的equals() ;
        test1.equals(test1);            //Test1中的equals() ;    只有这里打印出"haha"。
    }
}


       问题二:HashCode的作用?
            原理:优点:“空间换时间”原则,提高了查找速率。因为先查找对应的hash code从小范围获取地址,然后在从桶中查找key值从而查找对应元素。
                       缺点:不适合多个数据相同的情况。因为极端情况在只有一个或两个桶,那么查找的速率跟一般存储一样,但是却浪费了空间。

             javaSE6 约定:
                    ①对象没改变,返回统一hashCode。
                    ②如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
                    ③如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。
            原理:机器相同,相同程序,运行环境相同的情况下。对象值域相同则生成的hashCode也是相同的。反则则不然。
                       所以equals()相等的情况下hashCode()肯定相等,但是hashCode()相等的情况下equals()不一定相等。

            

        问题三:覆盖equals()要覆盖hashCode()的必要性?
            hashCode可变性:自定类型和某些没有覆盖hashCode()的类,不同的机器hashCode会不同。
            必要性:当用到Hash表的时候必要!使到Hash表里面的每个桶里面的对象相等。
                                    ①集合框架, 为什么要覆写集合中元素类型equals()呢,因为在java的集合框架中,key值是通过equals来判断两个对象是否相等的。
                                    ②自定义的类,如果没有实现HashCode()方法的话,new出来的自定义类的地址是不一样的,那么对应的HashCode()也是不一样的,所以在Set里面可以插入两个值域相同但地址不同的对象。当然此时      
                                         的equals方法也不相等。
        

equals实例:

(1)Object类:仅仅判断引用是否相同
public boolean equals(Object obj) {
        return (this == obj);
}

(2)String类:覆写Object
public boolean equals(Object anObject) {
        if (this == anObject) { //引用是否相等
            return true;
        }
        if (anObject instanceof String) {    //是否是同一类
            String anotherString = (String) anObject;
            int n = count;
            if (n == anotherString.count) {   //长度是否一致
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = offset;
                int j = anotherString.offset;
                while (n-- != 0) {                  //逐个字符判断是否相等
                    if (v1[i++] != v2[j++])     //基本类型按照ASCII码值判断相等。
                        return false;
                }
                return true;
            }
        }
        return false;
}



hashCode实例:

(1)Object类:hashCode()是本地方法,不同机器hashCode()不同
public native int hashCode();

        (2)String类:解释一下这个程序(String的API中写到): 
                   s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 
                   使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为 0。) 
public int hashCode() {
        int h = hash;
        if (h == 0) {
            int off = offset;
            char val[] = value;
            int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值