Java equals方法的两种重写场景及方式讲解,javaequals
Java equals方法的两种重写场景及方式讲解,javaequals
相信大部分同行都遇到过这样的问题,'=='与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方法的重写还得根据你自己的需求进行定制化。
用户点评