Preferred Equals() Method Implementation

java

Solution

Do not override equals for things that are not mathematically equal.

You might think it is a good idea to do

User bob = new User("Bob");
if (bob.equals("Bob")) {
  ...
}

but it rarely is. Do you want all of the equals observing code getting confused when `Strings` are "equal" to `Users`?

If you want a lookup method, write it

class User {

    private String id;

    public boolean equals(Object obj) {
        if (obj instanceof User) {
            User other = (User)obj;
            if (id.equals(other.id)) {
              return true;
            }
        }
        return false;
    }

    public String getId() {
        return id;
    }

}

Then the code elsewhere to maintain the "fast lookup" table.

Map<String, User> idTable = new HashMap<String, User>();
User bob = new User("Bob");
idTable.put(bob.getId(), bob);

public User findUser(String id) {
  return idTable.get(id);
}

Note that this doesn't mess around with the equals implementation, so now you can safely have `Sets` of `Users`, `Lists` of `Users`, etc. all without worrying if somehow a String will foul the works.

Now if you can't find a good place to maintain a `Map` of `Users` indexed by their `id`, you can always use the slower `Iterator` solution

List<User> users = new List<User>();
users.add(new User("Bob"));
users.add(new User("Steve"));
users.ass(new User("Ann"));

public User findUser(String id) {
  Iterator<User> index = users.iterator();
  while (index.hasNext()) {
    User user = index.next();
    if (id.equals(user.getId())) {
      return user;
    }
  }
  return null;
}

Problem

This is a question about how to implement the equals method when I need to find instance of the object in a List given a value that one of the instances my have in their member. I have an object where I've implemented equals: ``` class User { private String id; public User(id) { this.id = id; } public boolean equals(Object obj) { if (!(obj instanceof User)) { return false; } return ((User)obj).id.equals(this.id); } } ``` Now if I want to find something in the List I would do something like this: ``` public function userExists(String id) { List<Users> users = getAllUsers(); return users.contains(new User(id)); } ``` But perhaps this might be a better implementation? ``` class User { private String id; public boolean equals(Object obj) { if (!(obj instanceof User)) { return false; } if (obj instanceof String) { return ((String)obj).equals(this.id); } return ((User)obj).id.equals(this.id); } } ``` With this instead: ``` public function userExists(String id) { List<Users> users = getAllUsers(); return users.contains(id); } ```

Original source