黑马程序员技术交流社区

标题: 关于equals实现的问题 [打印本页]

作者: 龚建锋    时间: 2012-7-30 08:31
标题: 关于equals实现的问题
//equals的使用练习
public class Equals {
public static void main(String[] args) {
  Compare c1 = new Compare("hah", 23);
  Compare c2 = new Compare("ha", 23);
  System.out.println(c1);
  System.out.println(c2);
  System.out.println(c1 == c2);
  System.out.println(c1.equals(c2));
}
}
class Compare {
private String name;
private int age;
public Compare(String name, int age) {
  this.name = name;
  this.age = age;
}
// 重写equals方法,toString()方法
public String toString() {
  return "Compare{" + name + "," + age + "}";
}
public boolean equals(Object obj) {
  if (this == obj)// 地址相同, 代表是同一个对象, 属性肯定相同, 直接返回true
   return true;
  if (obj == null)// 传入的对象如果为空, 不用比较直接返回false
   return false;
  if (!(obj instanceof Compare))// 如果obj不是Compare类型, 直接返回false
   return false;
  Compare other = (Compare) obj; // 为了访问name和age, 先将Object类型的实参强转回Compare类型
         
  if (this.name == null)// 如果名字一个为null另一个不为null, 返回false
   if (other.name != null)
    return false;
   else if (!this.name.equals(other.name)) // 如果name不同, 返回false
     return false;
  if (this.age != other.age)// 如果age不同, 返回false
   return false;
  
  return true;
}
}
/*
运行上面程序System.out.println(c1.equals(c2));本应该输出false,但结果却输出true。纠结良久,大家帮忙看看~~呵呵。如图:

*/

equals.jpg (17.55 KB, 下载次数: 100)

equals.jpg

作者: 刘真    时间: 2012-7-30 09:35
判断名字只要有一个为NULL时,两个if语句,一个返回语句,运行时出错,导致下面的语句未执行。
public String toString() {
  return "Compare{" + name + "," + age + "}";
}
public boolean equals(Object obj) {
  if (this == obj)// 地址相同, 代表是同一个对象, 属性肯定相同, 直接返回true
   return true;
  if (obj == null)// 传入的对象如果为空, 不用比较直接返回false
   return false;
  if (!(obj instanceof Compare))// 如果obj不是Compare类型, 直接返回false
   return false;
  Compare other = (Compare) obj; // 为了访问name和age, 先将Object类型的实参强转回Compare类型
         
if (this.name == null || other.name == null)// 只要有一个名字为NULL,则返回false。
       return false;

   else if (!this.name.equals(other.name)) // 如果name不同, 返回false
     return false;
  if (this.age != other.age)// 如果age不同, 返回false
   return false;
  
return true;

}
作者: 郑正华    时间: 2012-7-30 10:08
本帖最后由 郑正华 于 2012-7-30 10:26 编辑

楼主此处的代码写的有些不妥:

if (this.name == null)     ← 这里的外嵌if判断this.name是否为空,但你传入的name不为空,所以后面的else if判断语句就不执行了,直接执行判断年龄的语句,所以导致了名字不同,年龄相同,结果返回也是true;这里的代码还有个问题就是如果this.name为null,other.name也为null,程序就会报错,因为代码中没有对这种情况做处理。
if (other.name != null)         
    return false;
   else if (!this.name.equals(other.name))
     return false;
  if (this.age != other.age)
   return false;
  return true;
---------------------------------------------------------建议楼主改成以下代码就没问题了,还有就是提醒楼主," "和null不相同,空字符串也有值
   if (this.name == null && other.name!=null)
      return false;
    else if (!this.name.equals(other.name))
       return false;
    if (this.age != other.age)
     return false;
   
    return true;
作者: 涂金哲    时间: 2012-7-30 10:18
package com.cn.tt;

//equals的使用练习
public class Test {
public static void main(String[] args) {
Compare c1 = new Compare("hah", 23);
Compare c2 = new Compare("hah", 23);
System.out.println(c1);
System.out.println(c2);
System.out.println(c1 == c2);
System.out.println(c1.equals(c2));
}
}
class Compare {
private String name;
private int age;
public Compare(String name, int age) {
this.name = name;
this.age = age;
}
//重写equals方法,toString()方法
public String toString() {
return "Compare{" + name + "," + age + "}";
}
public boolean equals(Object obj) {
if (this == obj)// 地址相同, 代表是同一个对象, 属性肯定相同, 直接返回true
return true;
if (obj == null)// 传入的对象如果为空, 不用比较直接返回false
return false;


if (!(obj instanceof Compare))// 如果obj不是Compare类型, 直接返回false
        return false;
       
Compare other = (Compare) obj;

// 为了访问name和age, 先将Object类型的实参强转回Compare类型      
        if (this.name == null)// 如果名字一个为null另一个不为null, 返回false
                if (other.name != null)
                        return false;
                else if (!this.name.equals(other.name)) // 如果name不同, 返回false
                        return false;
        if (this.age != other.age)// 如果age不同, 返回false       
                return false;
        return this.name==other.name;//此处的返回值被你限定了 应该是这样的
       
}
}
/*
运行上面程序System.out.println(c1.equals(c2));本应该输出false,但结果却输出true。纠结良久,大家帮忙看看~~呵呵。如图:

*/
逻辑上的错误 呵呵

作者: 王渠    时间: 2012-7-30 10:20
public class Equals {
        public static void main(String[] args) {
                Compare c1 = new Compare("hah", 23);
                Compare c2 = new Compare("ha", 23);
                System.out.println(c1);
                System.out.println(c2);
                System.out.println(c1 == c2);
                System.out.println(c1.equals(c2));
        }
}

class Compare {
        private String name;
        private int age;

        public Compare(String name, int age) {
                this.name = name;
                this.age = age;
        }

        // 重写equals方法,toString()方法
        public String toString() {
                return "Compare{" + name + "," + age + "}";
        }

        public boolean equals(Object obj) {
                if (this == obj)// 地址相同, 代表是同一个对象, 属性肯定相同, 直接返回true
                        return true;
                if (obj == null)// 传入的对象如果为空, 不用比较直接返回false
                        return false;
                if (!(obj instanceof Compare))// 如果obj不是Compare类型, 直接返回false
                        return false;
                Compare other = (Compare) obj; // 为了访问name和age,
                                                                                // 先将Object类型的实参强转回Compare类型
                if(other.name==null)//如果说是姓名不存在就返回false,年龄是数字,不存在空的情况
                        return false;
               
                if (this.name.equals(other.name)&&this.age==other.age) // 如果姓名,年龄都相等,返回真。否则返回假
                        return true;

                return false;
        }
}

上面是帮你修改过后的方法,String类型的name是有可能为空的,但整数类型的年龄是不会为空的。

所以判断一次name是否为空即可









作者: 王程    时间: 2012-7-30 10:35
if (this.name == null)//-->1  
   if (other.name != null)
    return false;
   else if (!this.name.equals(other.name)){ // 如果name不同, 返回false
  System.out.println("dafeaefaf");   
  return false;}
  if (this.age != other.age)//-->2
   return false;
  return true;
程序在1处时,先判断name是否为空,如果不为空,则直接判断2处年龄是否相等,所以代码的执行效果是只要名字不为空,只要年龄相等,就返回true,所以结果当然出错了
作者: 杜佳瑞    时间: 2012-7-30 10:56
本帖最后由 杜佳瑞 于 2012-7-30 10:57 编辑

这个问题其实很简单,大家都知道问题出现在下面两句话,一旦name不为空就不会执行else if语句,这是因为程序执行时else if会自动找上面与它最近的语句,所以虚拟机会认为 if (other.name != null)
和else if是一个整体,这样this.name不为空就会直接跳过else if,所以这样将 { if (other.name != null)
    return false; }括起来就能实现楼主想要的结果了。
if (this.name == null)        
    if (other.name != null)//默认是一个整体
    return false;
else if (!this.name.equals(other.name))
    return false;

作者: 龚建锋    时间: 2012-7-30 13:19
呵呵~~谢谢大家了~~找到问题点了~~





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2