覆盖equals方法

时间:2011-05-13 13:00:39

标签: java

我正在修改考试。在过去的论文中有一个问题,

覆盖以下类中的equals方法。该方法应检查 整个国家的内容平等。

 class Employee
    {
        String firstName;
        int age;
    } 

[2分]

我做了一些摆弄正确答案,并且到目前为止已经提出了这个问题。有没有更简单的方法来回答这个问题,这是对的吗?非常感谢您的帮助。

 public class Employee
    {

     int age;

    public boolean equals(Object obj)
    {
        if(this == obj)
            {
                return true; //Reference equality.
            }    
        if(!(obj instanceof Employee)) 
            {
                return false; // not the same type.
            }
        Employee other = (Employee) obj;
        return firstName == other.firstName;
        return age == other.age;
        }
    }

7 个答案:

答案 0 :(得分:1)

有几点:

  1. 您需要检查obj是否为null
  2. 要比较Java中的String内容,请使用equals(),即firstName.equals(other.firstName)。首先查看firstName是否为null
  3. 这是一个改进的实现:

    public boolean equals(Object obj)
    {
      if(obj == null)
      {
        return false;
      }
      if(this == obj)
      {
        return true; //Reference equality.
      }    
      if(this.getClass() != obj.getClass())
      {
        return false;
      }
      Employee other = (Employee) obj;
      if(firstName == null)
      {
        if(other.firstName != null)
        {
          return false;
        }
      }
      else if(!firstName.equals(other.firstName))
      {
        return false;
      }
      return age == other.age;
    }
    

    编辑:根据@Mark Peters的回答更新了类型比较,使equals()对称。

答案 1 :(得分:1)

使用

return (((this.firstName == null || other.firstName == null)
            && this.firstName == other.firstName)
       ||
       this.firstName.equals(other.firstName))
       && age == other.age;

这也处理null个案例。

答案 2 :(得分:1)

String firstName应与.equals(),NOT ==进行比较。 == compare对于原始int age字段是可以的。

如果两个firstNames相同但年龄不相等怎么办?这不应该失败吗?

return (firstName.equals(obj.firstName)) && (age == obj.age);

这样的东西

当然,当this.firstName为null时,不会考虑这种情况,这会导致NullPointerException被抛出。

如果员工的firstNames都为null,那么员工是否被认为是平等的?如果一个是null而另一个不是?假设两者都必须为null,或者两者都必须是String.equals(),则可以使用:

return ((null == firstName && null == obj.firstName) 
  || (null != firstName && firstName.equals(obj.firstName)))
  && (age == obj.age);

而不是你的2个返回语句。其余的看起来还不错。

答案 3 :(得分:1)

有一点需要注意,我不认为你会在考试中停下来......

当课程不是最终时,做instanceof通常是不好的做法。原因是equals()必须是对称的。接受子类(也可能使用自己的新方面实现等于)可能导致它不对称。

示例(我认为该示例与 Effective Java 2ed 中使用的示例相同):

class Point {
    protected int x, y;
    //equals method uses instanceof Point and checks x and y values are the same
}

class ColorPoint extends Point {
    protected Color color;
    //equals method checks that it's a ColorPoint, that super.equals is true, 
    //then checks the Color
}

new Point(1, 2).equals(new ColorPoint(1, 2, Color.red)); //true
new ColorPoint(1, 2, Color.red).equals(new Point(1, 2)); //false

这是一个非常微妙的观点,即使大多数答案者都没有考虑到这一点。但这就是大多数equals生成器(例如您最喜欢的IDE中的生成器)倾向于进行精确的类比较的原因:

  if ( this.getClass() != other.getClass() ) {
     return false;
  }

当equals方法使用instanceof时,通常很好地记录子类必须遵循完全相同的规范。

答案 4 :(得分:0)

你的最后一行,年龄比较,无法到达;你不应该使用==来比较字符串;并且您需要考虑空值。

由于总体运动似乎是为你全力以赴,这里是Eclipse的实现:

public class Employee {
    private final String firstName;
    private final int age;

    public Employee(final String firstName, final int age) {
        super();
        this.firstName = firstName;
        this.age = age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Employee other = (Employee) obj;
        if (age != other.age) {
            return false;
        }
        if (firstName == null) {
            if (other.firstName != null) {
                return false;
            }
        } else if (!firstName.equals(other.firstName)) {
            return false;
        }
        return true;
    }
}

并进行了一系列测试:

import org.junit.Test;

public class EmployeeTest {
    @Test
    public void testEmployeeEquals() {
        final Employee nullNameEmp = new Employee(null, -1);
        final Employee empA1 = new Employee("a", 1);
        final Employee empA1Clone = new Employee("a", 1);
        final Employee empA2 = new Employee("a", 2);
        final Employee empB1 = new Employee("b", 1);
        final Employee empB2 = new Employee("b", 2);
        final Employee subEmp = new Employee("a", 1) {

        };

        assert !nullNameEmp.equals(empA1);
        assert !nullNameEmp.equals(empA1Clone);
        assert !nullNameEmp.equals(empA2);
        assert !nullNameEmp.equals(empB1);
        assert !nullNameEmp.equals(empB2);
        assert !nullNameEmp.equals(subEmp);
        assert !nullNameEmp.equals(null);

        assert !empA1.equals(nullNameEmp);
        assert empA1.equals(empA1Clone);
        assert !empA1.equals(empA2);
        assert !empA1.equals(empB1);
        assert !empA1.equals(empB2);
        assert !empA1.equals(subEmp);
        assert !empA1.equals(null);

        assert !empA2.equals(nullNameEmp);
        assert !empA2.equals(empA1);
        assert !nullNameEmp.equals(empA1Clone);
        assert !empA2.equals(empB1);
        assert !empA2.equals(empB2);
        assert !empA2.equals(subEmp);
        assert !empA2.equals(null);

        assert !empB1.equals(nullNameEmp);
        assert !empB1.equals(empA1);
        assert !empB1.equals(empA1Clone);
        assert !empB1.equals(empA2);
        assert !empB1.equals(empB2);
        assert !empB1.equals(subEmp);
        assert !empB1.equals(null);

        assert !empB2.equals(nullNameEmp);
        assert !empB2.equals(empA1);
        assert !empB2.equals(empA1Clone);
        assert !empB2.equals(empA2);
        assert !empB2.equals(empB1);
        assert !empB2.equals(subEmp);
        assert !empB2.equals(null);

        assert !subEmp.equals(nullNameEmp);
        assert !subEmp.equals(empA1);
        assert !subEmp.equals(empA1Clone);
        assert !subEmp.equals(empA2);
        assert !subEmp.equals(empB1);
        assert !subEmp.equals(empB2);
        assert !subEmp.equals(null);

        assert nullNameEmp.equals(nullNameEmp);
        assert empA1.equals(empA1);
        assert empA1Clone.equals(empA1Clone);
        assert empA2.equals(empA2);
        assert empB1.equals(empB1);
        assert empB2.equals(empB2);
        assert subEmp.equals(subEmp);
    }
}

答案 5 :(得分:0)

public boolean equals(Object o){
   if(this==o){ //same instance, no need to check more
       return true;
   }
   if(o instanceof Employee){ //when null this will yield false
       Employee other = (Employee) o;
       return (this.name == other.name || (this.name != null && this.name.equals(other.name)) && this.age == other.age;
   }
   return false;
}

答案 6 :(得分:0)

在一个答案中汇总所有已经提及的部分:

public boolean equals(Object obj) {
    if(this == obj) {
        return true; //Reference equality.
    }
    if(obj == null || !(obj instanceof Employee))
    {
        return false; // not the same type.
    }
Employee other = (Employee) obj;
return (firstName.equals(other.firstName) && age == other.age);
}