Как я могу реализовать мудрое сравнение членов в Java? - PullRequest
3 голосов
/ 22 января 2010

Я из C ++ фона и только начал Java сегодня. Скажем, у меня есть класс с парой членов данных. Например:

public class Person {
    //Constructors/Destructor
    public Person(String strFirstName, String strLastName) {
        m_strFirstName = strFirstName;
        m_strLastName = strLastName;
        m_strFullName = m_strFirstName + m_strLastName;
    }

    //Getters
    public String GetFullName() { return m_strFullName; }
    public String GetFirstName() { return m_strFirstName; }
    public String GetLastName() { return m_strLastName; }

    //Private Data Members
    private String m_strFirstName;
    private String m_strLastName;
    private String m_strFullName;
}

Теперь допустим, я делаю это:

Person john = new Person("john", "doe");
Person johndoe = new Person("john", "doe");
if (john == johndoe) {
    System.out.println("They are Equal");
} else {
    System.out.println("They are NOT Equal");
}

Здесь результат «Они НЕ равны». Я понимаю, что это потому, что Java сравнивает ссылки (адреса памяти), и поскольку они находятся в разных местах памяти, тест не пройден. Я читал, что Java не поддерживает перегрузку операторов, поэтому я не могу перегрузить оператор ==, поэтому есть ли метод, который я бы переопределил для реализации моего членного сравнения? Метод object.equals выглядел многообещающе, но я читал, что не рекомендуется переопределять этот метод.

UPDATE: Хорошо, я убежден, что переопределение равно ОК! Я не могу найти ту статью, в которой говорится, что это плохо. Спасибо за помощь, у меня, вероятно, будет больше вопросов по мере изучения Java!

Ответы [ 2 ]

6 голосов
/ 22 января 2010

Вы делаете:

if (john.equals(johndoe)) {
  ...
}

и реализуйте метод equals() на вашем объекте:

public class Person {
  private String firstName;
  private String lastName;
  private String fullName;

  public Person(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.fullName = firstName + lastName;
  }

  public String getFirstName() { return firstName; }
  public String getLastName() { return lastName; }
  public String getFullName() { return fullName; }

  @Override
  public boolean equals(Object ob) {
    if (ob == null) return false;
    if (ob.getClass() != getClass()) return false;
    Person other = (Person)ob;
    if (!firstName.equals(other.firstName)) return false;
    if (!lastName.equals(other.lastName)) return false;
    if (!(fullName.equals(other.fullName)) return false;
    return true;
  }

  @Override
  public int hashCode() {
    return firstName.hashCode() ^ lastName.hashCode() ^ fullName.hashCode();
  }
}

Две вещи на заметку:

  1. Выше приведено больше в стиле Java, чем в стиле C ++. Я настоятельно рекомендую вам принять соглашения о кодировании Java при кодировании Java. Если вы новичок в Java, вы должны попытаться изучить их; и
  2. Java имеет контракт equals / hashCode, означающий, что если два объекта равны, то их хеш-коды должны быть равными.
2 голосов
/ 22 января 2010

Где вы читали, что это плохая практика? Очень распространено перегружать equalshashCode) в Java. См. Какие проблемы следует учитывать при переопределении equals и hashCode в Java? .

...