深入equals方法对象相等比较

equals方法的重要性毋须多言,只要你想比较的两个对象不愿是同一对象,你就应该实现equals方法,让对象用你认为相等的条件来进行比较.下面的内容只是API的规范,没有什么太高深的意义,但我之所以最先把它列在这儿,是因为这些规范在事实中并不是真正能保证得到实现.

1.对于任何引用类型, o.equals(o)==true 成立.

2.如果 o.equals(o1)==true 成立,那么o1.equals(o)==true也一定要成立.

3.如果 o.equals(o1)==true 成立且o.equals(o2)==true 成立,那么o1.equals(o2)==true 也成立.

4.如果第一次调用o.equals(o1)==true 成立再o和o1没有改变的情况下以后的任何次调用都成立.

5.o.equals(null)==true 任何时间都不成立.

以上几条规则并不是最完整的表述,详细的请参见API文档.对于Object类,它提供了一个最最严密的实现,那就是只有是同一对象是,equals方法才返回true,也就是人们常说的引用比较而不是值比较.这个实现严密得已经没有什么实际的意义,所以在具体子类(相对于Object来说)中,如果我们要进行对象的值比较,就必须实现自己的equals方法.

先来看一下以下这段程序:

public boolean equals(Object obj)
  {
    if (obj == null) return false;
    if (!(obj instanceof FieldPosition))
      return false;
    FieldPosition other = (FieldPosition) obj;
    if (attribute == null) {
      if (other.attribute != null) {
        return false;
      }
    }
    else if (!attribute.equals(other.attribute)) {
      return false;
    }
    return (beginIndex == other.beginIndex
      && endIndex == other.endIndex
      && field == other.field);
  }

这是JDK中java.text.FieldPosition的标准实现,似乎没有什么可说的.我信相大多数或绝大多数程序员认为,这是正确的合法的equals实现.毕竟它是JDK的API实现啊.还是让我们以事实来说话吧:

package debug;
import java.text.*;
public class Test {
 public static void main(String[] args) {
  FieldPosition fp = new FieldPosition(10);
  FieldPosition fp1 = new MyTest(10);
  System.out.println(fp.equals(fp1));
  System.out.println(fp1.equals(fp));
 }
}
class MyTest extends FieldPosition{
 int x = 10;
 public MyTest(int x){
  super(x);
  this.x = x;
 }
 public boolean equals(Object o){
  if(o==null) return false;
  if(!(o instanceof MyTest )) return false;
  return ((MyTest)o).x == this.x;
 }
}

运行一下看看会打印出什么:

System.out.println(fp.equals(fp1));打印true

System.out.println(fp1.equals(fp));打印flase

时间: 2025-01-23 18:41:56

深入equals方法对象相等比较的相关文章

对象-java中重写equals方法为什么不直接在里面比较hashcode()?

问题描述 java中重写equals方法为什么不直接在里面比较hashcode()? 看书上说只要重写在一个类中重写equals方法,那就一定要重写hashcode方法,因为两个对象只要equals返回值为true,那么他俩的hashcode就一定相同. 那为什么不可以提前先写好hashcode函数,然后在equals函数里面直接来一行if(this.hashcode() == otherObject.hashcode()) return true;else return false;就行了?

马士兵J2SE-第三章-面向对象-Object类:toString方法、equals方法、对象转型、抽象类抽象方法、final关键字、接口

toString方法 public class test { public static void main(String[] args) { Teacher t=new Teacher(); System.out.println("1 "+t+" 2 "+t.toString()); } } class Teacher { public String toString() { return "I am a teacher"; } } 输出: 1

为什么我new了3个Teacher对象,也覆盖了hashcode跟equals方法,而TreeSet中只有一个对象

问题描述 publicclassTeacherimplementsComparable<Teacher>{privateStringname;privateintage;privatedoublesalary;privateDatebirth;publicTeacher(Stringname,intage,doublesalary,Datebirth){super();this.name=name;this.age=age;this.salary=salary;this.birth=birth

java基础-JAVA equals方法被调用时字符串和对象的顺序

问题描述 JAVA equals方法被调用时字符串和对象的顺序 如图所示 equals方法中对象在前还是字符串在前? 是标准还是建议? 解决方案 一般建议是字符串在前,这样能够避免当你的对象为[null] 的时候,报空指针异常. 解决方案二: 字符串在前,避免当你的对象为[null] 的时候,报空指针异常

Java中判断对象是否相等的equals()方法使用教程_java

Object类中的equals方法用于检测一个对象是否等于另一个对象.在Object类中,这个方法判断两个对象是否具有相同的引用,如果两个对象具有相同的引用,它们一定是相等的.从这点上看,将其作为默认操作也是合乎情理的.然而,对于多数类类说,这种判断并没有什么意义,例如,采用这种方式比较两个PrintStream是否相等就完全没有意义.然而,经常需要检测两个对象状态的相等性,如果两个对象的状态相等,就认为这两个对象是相等的.所以一般在自定义类中都要重写equals比较. 下面给出编写一个完美eq

对象-java的equals方法重写中的小问题

问题描述 java的equals方法重写中的小问题 public boolean equals(Object otherObject) { // a quick test to see if the objects are identical if (this == otherObject) return true; // must return false if the explicit parameter is null if (otherObject == null) return fal

如何编写高质量equals方法

什么是equals方法 指示其他某个对象是否与此对象相等,equals方法存在Object类中,我们编写的类继承Object,可以覆盖Object的equals方法来实现我们的逻辑,去判断两个对象是否相等. Object类中的equals方法 一起来看看Object类中的源代码 public boolean equals(Object obj) { return (this == obj); } 我们可以观察到几点: equals方法是public修饰的,外部类是可以访问的 equals方法的返

Java:所有的equals方法实现都是错误的?

本文介绍了一种改写(override)equals 方法的技巧.使用该技巧,即使在实体类的子类添加了新的域(field)时,仍然能够满足 equals 方法的约定. 在<Effective Java>一书的第 8 条目中,Josh Bloch 将子类化时满足 equals 约定这一困难描述为:面向对象语言中等值关系的最根本问题.Bloch 这样写道: 不存在一种方式,能够在扩展非实例类并添加值组件的同时,仍然满足equals的约定.除非你愿意放弃面向对象的抽象性这一优点. <Progra

如何在Java中避免equals方法的隐藏陷阱

译者注 :你可能会觉得Java很简单,Object的equals实现也会非常简单,但是事实并不是你想象的这样,耐心的读完本文,你会发现你对Java了解的是如此的少.如果这篇文章是一份Java程序员的入职笔试,那么不知道有多少人会掉落到这样的陷阱中. 摘要 本文描述重载equals方法的技术,这种技术即使是具现类的子类增加了字段也能保证equal语义的正确性. 在<Effective Java>的第8项中,Josh Bloch描述了当继承类作为面向对象语言中的等价关系的基础问题,要保证派生类的e