如何为类定义多个equals()函数

时间:2010-06-26 14:22:30

标签: java

我想在名为MyObject的类中覆盖“public boolean equals(Object obj)”函数,名称和年龄,其结构如下所示

public class MyObject{
       private String name;
       private int age;
}

我怎么样?

@balusC:

这个怎么样?

vo  = new MyObject() {
                    public boolean equals(Object obj) {
                        return ((MyObject)obj).name().equals(this.getName());

                    }


vo  = new MyObject() {
                    public boolean equals(Object obj) {
                        return ((MyObject)obj).age() == (this.getAge());

6 个答案:

答案 0 :(得分:6)

您的问题有点模糊,但如果唯一的目的是根据您要使用的属性而使用不同的排序算法,那么请使用Comparator

public class Person {
    private String name;
    private int age;

    public static Comparator COMPARE_BY_NAME = new Comparator<Person>() {
        public int compare(Person one, Person other) {
            return one.name.compareTo(other.name);
        }
    }

    public static Comparator COMPARE_BY_AGE = new Comparator<Person>() {
        public int compare(Person one, Person other) {
            return one.age > other.age ? 1
                 : one.age < other.age ? -1
                 : 0; // Maybe compare by name here? I.e. if same age, then order by name instead.
        }
    }

    // Add/generate getters/setters/equals()/hashCode()/toString()
}

您可以使用如下:

List<Person> persons = createItSomehow();

Collections.sort(persons, Person.COMPARE_BY_NAME);
System.out.println(persons); // Ordered by name.

Collections.sort(persons, Person.COMPARE_BY_AGE);
System.out.println(persons); // Ordered by age.

对于实际的equals()实现,当两个Person对象在技术上或自然相同时,我宁愿让它返回true。您可以使用DB生成的PK来比较技术标识:

public class Person {
    private Long id;

    public boolean equals(Object object) {
        return (object instanceof Person) && (id != null) 
             ? id.equals(((Person) object).id) 
             : (object == this);
    }
}

或者只是比较每个属性以比较自然身份:

public class Person {
    private String name;
    private int age;

    public boolean equals(Object object) {
        // Basic checks.
        if (object == this) return true;
        if (object == null || getClass() != object.getClass()) return false;

        // Property checks.
        Person other = (Person) object;
        if (name == null ? other.name != null : !name.equals(other.name)) return false;
        if (age != other.age) return false;

        // All passed.
        return true;
    }
}

当您覆盖hashCode()时,不要忘记覆盖equals()

另见:

答案 1 :(得分:3)

我不确定你的目标是什么。 equals()的一般期望是它返回false null和其他类的对象,并在相关类的相关字段上执行值相等。

虽然您可以通过以下方式处理StringInteger

public boolean equals(Object o) {
  if (o == null) return false;
  if (o instanceof String) return name.equals(o);
  if (o instanceof Integer) return ((Integer)o) == age;
  ...
}

这违反了equals的合同,因此无法执行此操作(除非出现非常奇怪的错误)。

equalsequivalence relation,所以它必须是自反,对称和传递的。这里的对称部分是关键,因为a.equals(b)然后是b.equals(a)StringInteger都不会为您做到这一点。

如果您只想要帮助函数检查名称或年龄是否等于给定的名称/年龄,那么您可以在不使用equals()的情况下执行此操作:

public boolean equalsName(String name) { return name.equals(this.name); }
public boolean equalsAge(int age) { return age == this.age; }

答案 2 :(得分:2)

保持简短(简称 KISS 原则):写 setters getters 。类似于以下示例中的内容:

public class Person {  
  private String name;  
  private int age;  

public String getName() {  
  return name;  
}

public int getAge() {  
  return age;  
}

然后在你需要进行检查的方法中你可以写:

Person person = new Person();
if(person.getName().equals("Something")) doThis();
if(person.getAge() == 1337) doThat();

答案 3 :(得分:0)

如果你想覆盖equals,它应该是这样的:

static private <T> boolean checkEquals(T t1, T t2)
{
   return (t1 == null) ? (t2 == null) : t1.equals(t2);
}
@Override public boolean equals (Object o)
{
   if (o instanceof MyObject)
   {
     MyObject obj = (MyObject)o;
     return checkEquals(this.name, obj.getName()) 
         && this.age == o.getAge();
   }
   else
     return false;
}

@Override public int hashCode() 
{
   // implement hashCode
}

您需要覆盖两者 hashCode()和equals()或两者都不。 And you also should make sure your class is final, otherwise there are potential pitfalls with equals

答案 4 :(得分:0)

不确定“多重等于()”是什么意思。如果你想比较两个字段,你只需要覆盖这样的equals方法,

public boolean equals( Object o )
{
    if ( o != null && o instanceof MyObject )
    {
        MyObject m = (MyObject) o;
        if (this.name == null)
            return false;
        return this.name.eqauls(m.name) && this.age == m.age;
    }
    return false;
}

/// Compute a hash code for the pair.
public int hashCode()
{
    int code = name == null ? 0 : name.hashCode();
    return code ^ age;
}

每当你改变equals时改变hashCode是一个好习惯,这样HashMap就能有效地与你的对象一起工作。

答案 5 :(得分:0)

public class MyObject { 
    private String name; 
    private int age; 

    @Override
    public boolean equals(Object o){
        if(o instanceof MyObject){
            MyObject otherObject = (MyObject)o;
            if(name == null){
                return otherObject.name == null && otherObject.age == age;
            } else {
                return name.equals(otherObject.name) && otherObject.age == age;
            }
        } else {
            return false;
        }
    }

    // When we overriding equals it is a good practice to override hashCode
    // for consistecy
    @Override
    public int hashCode(){
        int nameCode = (name == null) ? 0 : name.hashCode();
        // See Item 9 in book Effective Java 2nd Edition
        return 31 * nameCode + age;
    }

}