对象的比较==,equals;equals和hashcode的覆写

Object类中equals和==是一个意思:比较2个对象的内存地址是否相同。

下面来看String这个封装类:覆写了equals方法和hashcode方法,

equals方法:

1.首先比较2个对象的地址是否相同,如果相同当然是一个对象

2.比较字符串每一个字符是否相等。

hashcode方法:相同字符串(无论是基础类型还是封装类型),计算出的hashcode都是一样的。

做一个例子:

下面来看下自义定的类:

只覆写此类中的equals方法:

 @Override
    public boolean equals(Object obj) {
       if(!(obj instanceof  Person)){
           //不是同类对象
           return false;
       }
       Person obj_person=(Person)obj;
       if(this.name.equals(obj_person.name)){
            return true;
       }else{
           return false;
       }
    }
//只覆写了equals方法
Person  personA=new Person("hx",12);
Person  personB=new Person("hx",19);
System.out.println("personA和personB两个是同一个对象吗 (==)?"+(personA==personB));//false
System.out.println("personA和personB equals吗 (equals)?"+(personA.equals(personB)));//true
System.out.println("personA的hashcode:"+personA.hashCode());//809191624
System.out.println("personB的hashcode:"+personB.hashCode());//69688117

覆写了equals+hashcode方法: 

@Override
public boolean equals(Object obj) {
   if(!(obj instanceof  Person)){
       //不是同类对象
       return false;
   }
   Person obj_person=(Person)obj;
   if(this.name.equals(obj_person.name)){
        return true;
   }else{
       return false;
   }
}

@Override
public int hashCode() {
    //用String类型的name的hashcode   相同的字符串hashcode是相同的,因为在String中覆写了hashcode
   return this.name.hashCode()*16;
}
//覆写equals+hashcode方法
Person  personA=new Person("hx",12);
Person  personB=new Person("hx",19);
Person  personC=personA;
Person  personD=new Person("hx",12);
System.out.println("personA和personB两个是同一个对象吗 (==)?"+(personA==personB));//false
System.out.println("personA和personB equals吗 (equals)?"+(personA.equals(personB)));//true
System.out.println("personA的hashcode:"+personA.hashCode());//53504
System.out.println("personB的hashcode:"+personB.hashCode());//53504
System.out.println("personD的hashcode:"+personD.hashCode());//53504
System.out.println("personC与personA是是同一个对象吗(==)?"+(personA==personC));//true
System.out.println("personA和personD两个是同一个对象吗 (==)?"+(personA==personD));//false
System.out.println("personA和personD两个是同一个对象吗 (equals)?"+(personA.equals(personD)));//true

结论:

未覆写equals情况下,A.equals(B) 或  A == B ,hashcode肯定相同(废话,未覆写的时候equals也是==)

覆写equals 情况下, A==B  hashcode相同, A.equals(B)  hashcode不一定相同(equals通过某一个属性来判断,比如name)

hashcode相同,并不一定相等(equals或==)。

1.非基本数据类型说相等要分清(==还是equals)

2.在不覆写的情况下,对象的equals也是调用== ,使用的是Object的方法,比较的还是内存地址值。

3.无论是覆写了equals 或  hashcode 还是  equals+hashcode,==只与内存地址有关,与equals还有hashcode是否覆写完全无关。

equals覆写后,A.equals(B)与hashcode是否覆写无关,只与你的覆写equals方法内的逻辑有关。

hashcode覆写,与hashset、hashmap等这种散列集合有关。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

☆重点:hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。

当集合HashMap要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就再调用它的equals方法与新元素进行比较,相同的话就覆盖,不相同就散列其它的地址 ,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

如果不覆写hashcode方法,

        Person p1 = new Person("Jack", 12);//p1
        System.out.println(p1.hashCode());
             
        HashMap<Person , Integer> hashMap = new HashMap<Person , Integer>();
        hashMap.put(p1, 1);
         
        System.out.println(hashMap.get(new Person ("Jack", 12)));//p2

get返回的是null 

只覆写的equals的情况下(不产生hash冲突的前提下),person1存入了hashmap,而person1.equals(person2) ----true  业务上可以理解为2个对象是相同的,但是用person2去hashmap中get的时候,由于hashcode没有覆写,导致person1和person2的hashcode不相等,所以hashmap取不到返回null.

更详细的可以参见:http://www.cnblogs.com/dolphin0520/p/3681042.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值