七、java的面向对象程序设计(详解equals方法)

来源:互联网 发布:less.js windows 编辑:程序博客网 时间:2024/05/28 23:13

七、java的面向对象程序设计(详解equals方法)

/**
 * 详解equals方法. 
 */
class Equals
{
 private int i;
 public void setI(int i)
 {
  this.i = i;
 }
 public Equals()
 {
  i = 1;
 }
 public Equals(int i)
 {
  this.i = i;
 }
}
class ChangeEquals
{
 private int i;
 public void setI(int i)
 {
  this.i = i;
 }
 public ChangeEquals()
 {
  i = 1;
 }
 public ChangeEquals(int i)
 {
  this.i = i;
 }
 //覆盖父类的equals方法,比较两个对象的成员变量i的值
 //如果相等返回true,不等返回false.
 public boolean equals(Object obj)
 {
  ChangeEquals ce = null;;
  if(obj instanceof ChangeEquals)
  {
   ce = (ChangeEquals)obj;
   if(this.i == ce.i)
    return true;
   else
    return false;
  }
  return false;
 }
}
public class EqualsTest {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  /*调用我们创建的类的默认equals方法*/
  System.out.println("调用我们创建的类的默认equals方法");
  Equals e1 = new Equals();//采用默认构造机
  Equals e2 = new Equals();
  System.out.println(e2.equals(e1));//false;
  Equals e3 = new Equals(20);//采用带参数的构造机
  Equals e4 = new Equals(20);
  System.out.println(e3.equals(e4));//false
  //通过以上实例证明,Equals类的成员变量i并不是equals方法判断的依据.原因如下:
  /*
  我们先来看看java.lang.Object这个类中的equals方法.
  public boolean equals(Object obj)
  {
    return (this == obj);
  }//~~~出自java的lang包
  Object类是所有类的父类,这里提供的equals方法只是对传入的对象和该对象类型本身做比较.
  当我们创建一个Equals类时,将自动继承Object类,于是也继承了Object类的equals方法.
  这里的equals方法实际上是以下形式:
  public boolean equals(Equals e)
  {
   return (this == e);
  }
  //我们创建了两个Equals的对象,并将这两个对象的首地址分别赋值给两个对象的引用e1和e2,
  //当我们打印e2.equals(e1)时,其实是在判断传递给equals方法的e1是否等于this,
  //而我们这里的this正好是e2这个引用,所以也就是判断e2是否等于e1.
  //这样,归根到底实际上是 e1 == e2 的判断.当然是false!
  */
  e1 = e3;
  System.out.println(e1.equals(e3));//true
  /* 这两行代码证实了我们的推断,即使e1和e3分别调用了不同的构造机,
   * 但是由于e1 = e3,也就是将e3所指向的对象的首地址赋值给了e1,e3和e1指向了同一个对象,所以判断的结果是true.
   */
  
  /*String类型和Integer类型*/
  //我们再来看看下面的情况:
  System.out.println("String,Integer等类型");
  Integer integers1 = new Integer(123);
  Integer integers2 = new Integer(123);
  System.out.println(integers1.equals(integers2));//true
  String str1 = new String();
  String str2 = new String();
  System.out.println(str1.equals(str2));//true
  String str3 = new String("abc");
  String str4 = new String("abc");
  System.out.println(str3.equals(str4));//true
  /*
  如果通过上面对Object类的equals的推论正确的话,那么String类和Integer类调用equals方法时,打印的结果应该为false,为什么会是true呢?
  原来String和Integer这些类在继承了Object类的同时覆盖了equals方法,
  我们先来看看java.lang.Integer类的equals方法.
  public boolean equals(Object obj)
  {
   if (obj instanceof Integer)
   {
       return value == ((Integer)obj).intValue();
      }
   return false;
     }
     该方法中通过instanceof比较运算符,对传入的类型和Integer类型进行了比较,再将传入的数值通过==操作符进行了对比.
     相同,我们再来看java.lang.String这个类中的equals方法.
      public boolean equals(Object anObject)
      {
   if (this == anObject)
   {
       return true;
   }
   if (anObject instanceof String)
   {
       String anotherString = (String)anObject;
       int n = count;
       if (n == anotherString.count)
       {
     char v1[] = value;
     char v2[] = anotherString.value;
     int i = offset;
     int j = anotherString.offset;
     while (n-- != 0)
     {
         if (v1[i++] != v2[j++])
      return false;
     }
     return true;
       }
   }
   return false;
     }
     该方法通过instanceof比较运算符,将传入的类型和String类型进行比较,并定义两个字符型数组,用于存放传入的字符串和原字符串.
     之后对比这两个字符数组中的元素.
     
     通过以上这两个类的源代码,我们得到一个结论,当我们创建一个类,想通过equals方法比较该类的两个对象的内容是否相等时,
     必须覆盖父类Object的equals方法.
   */
  
  /*调用我们创建的类并覆盖equals方法*/
  System.out.println("调用我们创建的类并覆盖equals方法");
  ChangeEquals ce1 = new ChangeEquals();
  ChangeEquals ce2 = new ChangeEquals();
  System.out.println(ce1.equals(ce1));
  System.out.println(ce1.equals(ce2));
  
  ChangeEquals ce3 = new ChangeEquals(20);
  ChangeEquals ce4 = new ChangeEquals(20);
  System.out.println(ce3.equals(ce4));
  
  System.out.println(ce1.equals(ce3));
  System.out.println(ce2.equals(ce4));
  
  ChangeEquals ce5 = new ChangeEquals(23);
  System.out.println(ce1.equals(ce5));
  System.out.println(ce3.equals(ce5));
  
  ce1.setI(10);
  ce2.setI(10);
  System.out.println(ce1.equals(ce2));
 }
}
/* ~~Console output~~
调用我们创建的类的默认equals方法
false
false
true
String,Integer等类型
true
true
true
调用我们创建的类并覆盖equals方法
true
true
true
false
false
false
false
true
 */

原创粉丝点击