两个冤家:==和equals

  • 关于==

由于数据类型分为基本类型(八种)和引用类型,所以下面分类来说:

  1. 针对于基本数据类型,如果是数值类型,则只要在数值上相同,就返回true
  2. 针对于引用类型:

        1)必须要求是同种类型的引用类型,即同属于一个类或父类,才能使用==进行对比,否则编译不通过;

2)返回true的条件是,对比双方必须是同一个对象,也就是说变量引用的地址是相同的,是内存中的同一个对象。

 

  • 关于equals
  1. 针对于基本数据类型,基本数据类型不能使用equals进行对比(没有此方法)
  2. 针对于引用类型来说, equals是Object自带的一个方法,在进行对比是,也是只有当双方指向同一个地址时,为同一个对象时,才返回true。

 

这里说说String类型,String本身是一个不可变类,所以同时新建两个new String(“123”)对象,使用equals方法的话,案例来说应该返回是false,因为他们不是一个对象,但实际结果却是返回了true。

 

原因是String的equals方法是默认重写过的,只要内容相同,就返回true,而不用指向同一个对象。(具体重写方法见就不说了)

同样,对于自定义的类来说,想要达到String类似的效果,如果有用到自定义类的比较此时就必须重写equals()方法,比如下面定义的类,重写了equals方法:

 

  测试:

         

    既然说到了equals,就不得不提hascode,老生常谈的一句话,重写了equals就一定要重写hashCode方法,那这又是为什么呢?我觉的最主要的一个原因在于set/map类的使用,关于这一点要先来HashSet和HashMap的工作原理。

 

  • HashMap的工作原理
  1. 结构及原理

下面是HasMap的结构是数组加链表,数组存放key值,链表中存放对应的value值,当项map中放入元素时,先调用hasCode(),获取到hash地址,再将该对象存放到对应的地址中。

这里重写hashcode的意义出来了,假设将上面说到的Person类,在不重写hashCode的情况下。同样是新建两各成员变量一样的Person实例,那么这时候是可以放入map中的,如下所示:

 

可以看到,两个对象都能成功放入到map中,可是在我们重写了equals之后,这两个对象应该是相等的,所以这里按我们的想法不应该都能放进去,只会存在一个数据。这就是因为equals重写过相同了,但是map中是先调用hasCode方法来进行地址的选择,因为这两个是不同的对象,肯定是有着不同的hash值(默认是对象的内存地址生成hash值),所以能放进去。为了解决这样的问题,就必须重写hascode方法,使这两个对象获取到相同hash值,阻止其放入到map中。

下面是重写Person类HashCode方法:

@Override

public int hashCode(){

    return age*name.hashCode();

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值