3

I'm from a C++ background and just started Java today. Say I have a class with a couple of data members. For example:

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;
}

Now lets say I do this:

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");
}

Here the result is "They are NOT Equal". I understand this is because Java is comparing the references (memory addresses), and since they are different locations in memory the test fails. I have read that Java doesn't support operator overloading, so I can't overload the operator==, so is there a method I'd override to implement my memberwise comparison? The object.equals method looked promising, but I've read that it's bad practice ot override this one.

UPDATE: Ok I'm convinced overriding equals is OK! I can't find that article that said that it's bad. Thanks for the help, I'll probably have more questions as I learn Java!!

cchampion
  • 7,607
  • 11
  • 41
  • 51

2 Answers2

5

You do:

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

and implement the equals() method on your object:

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

Two things to note:

  1. The above is more Java-style than C++-style. I'd highly suggest you adopt Java coding conventions when coding Java. If you're new to Java, you should try and learn them; and
  2. Java has an equals/hashCode contract meaning that if two objects are equal then their hash codes must be equal.
cletus
  • 616,129
  • 168
  • 910
  • 942
  • I read somewhere that you're not suppose to override equals, but I don't see why not.... I'll try to find that article again and post it. equals would seem like the correct way to me too. – cchampion Jan 22 '10 at 04:47
  • 1
    You are 100% absolutely supposed to override equals. – danben Jan 22 '10 at 04:48
  • The above code is perfect except that I don't think you will need to compare the full names as the full name field is obtained by appending the first name and the last name – Anand Sunderraman Jan 22 '10 at 04:56
  • @Anand: I had that same thought too. You could justifiably argue fullName isn't part of the state of the object, in which case you could also argue it shouldn't be a field at all or it should be `transient`. – cletus Jan 22 '10 at 05:06
  • I want to stress the `@Override`. An apparently common mistake is to provide an `equals(Person)` method that does not override. Also make the class `final` (and then you can use `instanceof` instead of `getClass()`. And the hash code algorithm isn't that great. – Tom Hawtin - tackline Jan 22 '10 at 05:24
2

Where did you read that it was poor practice? It is very common to overload equals (and hashCode) in Java. See What issues should be considered when overriding equals and hashCode in Java?.

Community
  • 1
  • 1
Brett Daniel
  • 2,001
  • 16
  • 17
  • I can't find that link right now, but if I do i'll post it. Everyone is saying override it though, so I'm convinced!! :) – cchampion Jan 22 '10 at 04:52