【问题标题】:How to define multiple equals() function for a class如何为一个类定义多个equals()函数
【发布时间】:2010-06-26 14:22:30
【问题描述】:

我想在名为 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());

【问题讨论】:

  • 顺便说一句:尽管人们说了什么,我认为你的问题的意图很明显

标签: java


【解决方案1】:

您的问题有点含糊,但如果唯一目的是根据您要使用的属性使用不同的排序算法,那么请使用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。您可以为此使用数据库生成的 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;
    }
}

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

另见:

【讨论】:

    【解决方案2】:

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

    虽然您当然可以通过以下方式处理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 的合同,所以你不能这样做(除非事情会以非常奇怪的方式出错)。

    equals 是一个equivalence 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; }
    

    【讨论】:

      【解决方案3】:

      保持简短(又名KISS原则):编写settersgetters。类似于以下示例:

      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();
      

      【讨论】:

        【解决方案4】:

        不确定您所说的“多重等于()”是什么意思。如果你想比较你的两个字段,你只需要像这样重写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 可以有效地处理您的对象。

        【讨论】:

        • 检查 o != null 是多余的 - null instanceof MyObject 将是错误的
        【解决方案5】:

        如果你确实想覆盖 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
        }
        

        您需要重写 both hashCode() 和 equals() 或都不重写。 And you also should make sure your class is final, otherwise there are potential pitfalls with equals.

        【讨论】:

          【解决方案6】:
          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;
              }
          
          } 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-04
            • 2021-07-31
            相关资源
            最近更新 更多