views:

79

answers:

2

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!!

+4  A: 

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
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
You are 100% absolutely supposed to override equals.
danben
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
@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
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
+2  A: 

Where did you read that it was poor practice? It is very common to overload equals (and hashCode) in Java. See http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java.

Brett Daniel
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