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