(Java-003)equals的两种重写场景及方式

相信大部分同行都遇到过这样的问题,'=='与equals方法的区别?其实这个不难回答,有些人认为('=='是比较两个对象的内存地址,equals方法是比较值的)其实这样的理解不能算错,但也不能算对。

先说说正解是什么?

正解:'=='与equals其实都是用来的比较两个对象的内存地址是否相同的,但是我们可以通过重写equals方法改变equals方法的默认行为,使其从比较地址变为比较值(例如String中就这样重写了equals方法,所以我们平常用到的字符串比较的equals是比较值的 -> 怕是我们平时遇到最多的也就是这个String中的equals吧)。

总而言之:equals方法比较灵活通过我们对其重写可以满足我们的定制化需求(比如既可以比较地址也可以比较值)

那么什么时候需要用到(比较地址或比较值)的我们重写的equals方法呢?这就涉及到使用场景:

场景一:比较两个对象的属性值是否相等,如果相等其两个对象也相等。

场景二:当我们向集合中添加对象的时候可能会添加同一个对象,加入我们有一个需求(同一个集合中不能添加两个及两个以上的同一个对象) => 比较两个对象的HashCode值是否相等,同时比较两个对象的属性值是否相等。

##针对于场景一的策略:(以String类中的equals方法为例)

public boolean equals(Object paramObject)
  {
    if (this == paramObject) {// 如果两个对象的内存地址相同(就是同一个对象),则一定相等
      return true;
    }
    if ((paramObject instanceof String))// 判断入参对象是否属于本类型(如果属于)
    {
      String str = (String)paramObject;// 复制一个对象(实际上就是将入参对象的地址赋给了str)
      int i = this.value.length;// 获取当前调用者对象的value属性值长度
      if (i == str.value.length)// 如果当前调用者对象的value属性值长度与str对象的属性值长度相等
      {
        char[] arrayOfChar1 = this.value;// 
        char[] arrayOfChar2 = str.value;// 分别将两个对象的value属性值赋值给字符型数组
        for (int j = 0; i-- != 0; j++) {// i-- != 0 => 意思就是规定这个for循环执行的次数
          if (arrayOfChar1[j] != arrayOfChar2[j]) {
            return false;
          }
          // 当两个字符型数组每个元素都相等的时候就返回true(次数未明写return true;是因为for循环外部已经返回了true)
        }
        return true;
      }
    }

总结:-1).先比较两个对象内存地址是否相等,如果内存地址都相等就代表着两个对象是同一个对象,所以自然相等。

        -2).再判断入参对象是否属于本类,如果属于就进行下面的判断如果不属于就直接返回false,即两个对象不相等(因为二者从属的类不是同一个)

        -3).再判断两个对象的属性值的长度是否一样长,如果一样长就进行后面操作,如果不一样长就返回false说明两个对象不相等。

        -4).再将比较两个对象的每个字符,如果每个字符都相等就代表这两个对象是相等的 ...

        -5).String类中的equals方法是比对值的,所以不需要对HashCode值进行比对,只需比对属性内容是否相等即可。  

##针对于场景二的策略:

public boolean equals(Person person) {
		/**
		 * 需求分析:
		 * 	-1).判断两个对象的HashCode值是否相等(如果HashCode值不相等的两个对象其一定不相等、但是HashCode相等的时候两个对象不一定是同一个对象)
		 *	-2).判断两个对象的内容是否相等
		 */
		if(this == person) return true;// 如果两个对象的引用地址都相等的话就说明是同一个对象(自然相等)
		if(person instanceof Person) {// 判断传进来的对象是否属于Person类
			Person obj = (Person) person;
			if(this.hashCode() == obj.hashCode()) {// 比对两个对象的hashCode值,如果两个对象的hashCode值相等两个对象不一定相等
												   // 但是如果两个对象的hashCode值不相等的话,这两个对象就不是同一个对象,也就不相等。
				if(this.name == null || obj.name == null) {
					return false;
				}else {
					if(this.name.equals(obj.name)) {// 如果两个对象的属性值相等,再加上上述条件则最终判断两个对象是同一个对象。
						return true;
					}else {
						return false;
					}
				}
			}else {
				return false;
			}
		}
		return false;
	}

总结:

-1).比较两个对象的地址值是否相等。

-2).判断入参对象是否属于本类。

-3).判断两个对象的hashCode值是否相等。

-4).判断两个对象的属性值是否相等。

-5).基于场景二的需求就必须进行hashCode值对比,以此来进一步确定对象是否是同一个对象。

以上就是在两种场景下我们对equals方法的重写。一个是仅仅根据属性值来判断两个对象是否相等、一个是根据属性值 + hashCode值对比来判断两个对象是否相等。!所对应的需求也各不相同,这里仅仅只是起到抛砖引玉的作用,具体的equals方法的重写还得根据你自己的需求进行定制化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值