java重写equals方法需要注意的几点

为什么equals()方法要重写?

判断两个对象在逻辑上是否相等,如根据类的成员变量来判断两个类的实例是否相等,而继承Object中的equals方法只能判断两个引用变量是否是同一个对象。这样我们往往需要重写equals()方法。

我们向一个没有重复对象的集合中添加元素时,集合中存放的往往是对象,我们需要先判断集合中是否存在已知对象,这样就必须重写equals方法。

覆盖equals方法需要遵守的规定

  • 1、自反性:对于任何非空引用x,x.equals(x)应该返回true。
  • 2、对称性:对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
  • 3、传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
  • 4、一致性:如果x和y引用的对象没有发生变化,那么反复调用x.equals(y)应该返回同样的结果。
  • 5、非空性:对于任意非空引用x,x.equals(null)应该返回false。

demo

public class Person {
    private String name;
  
    public Person(String name){
        this.name = name;
    }
  
    public String getName() {
        return name;
    }
  
    public void setName(String name) {
        this.name = name;
    }
  
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Person) {
            Person person= (Person) obj;
            return name.equalsIgnoreCase(person.getName().trim());
        }
        return false;
    }

   /*其他代码相同,不再赘述*/
     @Override
       public int hashCode(){
		return new HashCodeBuilder().append(name).toHashCode();

	}

    public static void main(String[] args){
        Person p1=new Person("张三");
        Person p2=new Person("张三    ");
        List<person> list = new ArrayList<person>();
        list.add(p1);
        list.add(p2);
        System.out.println("是否包含张三:"+list.contains(p1));
        System.out.println("是否包含张三:"+list.contains(p2));
    }
}

重新equals,必须重新hashcode

代码中的Person类与上一个相同,equals方法完美无缺。在这段代码中,我们在声明时直接调用方法赋值,这其实也是一个内部匿名类的操作。现在的问题是b1和b2这两个boolean值是否都为true?

我们先来看b1,Person类的equals覆写了,不再判断两个地址是否相等,而是根据人员的姓名来判断两个对象是否相等,所以不管我们的new Person(“张三”)产生了多少个对象,它们都是相等的。把“张三”对象放入list中,再检查list中是否包含,那结果肯定是true了。

接着来看b2,我们把张三这个对象作为了Map的键(Key),放进去的对象时张三,检查的对象还是张三,那应该和List的结果相同了,但是很遗憾,结果是false。原因何在呢?

原因就是HashMap的底层处理机制是以数组的方式保存map条目(Map Entry)的,这其中的关键是这个数组下标的处理机制:依据传入元素的hashCode方法的返回值决定其数组的下标,如果该数组位置上已经有了map条目,且与传入的键值相等则不处理,若不相等则覆盖;如果数组位置没有条目,则插入,并加入到map条目的链表中。同理检查键是否存在也是根据哈希码确定文职,然后遍历查找键值的。

那么对象元素的hashCode方法返回的是什么值呢?它是一个对象的哈希码,是由Object类的本地方法生成的,确保每个对象有一个哈希码(这也是哈希算法的基本要求:任意输入k,通过一定算法f(k),将其转换为非可逆的输出,对于两个输入k1和k2,要求若k1=k2,则必须f(k1)= f(k2),但不允许k1≠k2,f(k1)=f(k2)的情况存在)。

回到我们的例子上,由于我们没有重写hashcode方法,两个张三对象的hashcode方法返回值(也就是哈希码)肯定是不相同的,在HashMap的数组中也就找不到对应的Map条目了,于是就返回了false。

equls 与 hashcode的关系

equals 相等,hashcode一定相同

hashcode相等,equals 不一定相等。

转载于:https://my.oschina.net/u/3421984/blog/1794818

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值