首选Equals()方法实现

ude*_*eng 3 java

这是一个关于如何实现equals方法的问题,当我需要在List中找到对象的实例时给定一个值,该值是我的成员中的一个实例.

我有一个我实现了等于的对象:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我想在列表中找到一些东西,我会做这样的事情:

public function userExists(String id) {
        List<Users> users = getAllUsers(); 
        return users.contains(new User(id));
}
Run Code Online (Sandbox Code Playgroud)

但也许这可能是一个更好的实施?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

改为:

public function userExists(String id) {
    List<Users> users = getAllUsers(); 
    return users.contains(id);
}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 7

第二种方式是危险的,因为它打破了平等的对称属性.

Java期望实现equals()具有自反性,对称性和传递性.其次实现突破对称:如果你比较User一个String代表它的ID,你会得到true,但如果你的字符串比较给用户,你会得到一个false.

  • @udeleng no,创建一个虚拟用户来查找列表中的"User"是不合适的.使用`iterator`搜索列表,检查每个元素的字段,或者将用户存储在由id索引的`Map`中(如下面的示例所示).`user.equals(Object)`的_proper_实现要求您在列表中搜索之前已经拥有了您搜索的用户. (3认同)

Edw*_*uck 6

对于数学上不相等的事物,不要覆盖等于.

您可能认为这是一个好主意

User bob = new User("Bob");
if (bob.equals("Bob")) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

但它很少.你是否希望所有等于观察代码在Strings"等于" 时感到困惑Users

如果您想要查找方法,请编写它

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

}
Run Code Online (Sandbox Code Playgroud)

然后在其他地方的代码维护"快速查找"表.

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,这周围不乱用平等的实现,所以现在你可以放心地拥有SetsUsers,ListsUsers,等所有这些都不担心,如果莫名其妙的String将犯规的作品.

现在,如果你找不到一个好的地方来维护它们MapUsers索引id,你总是可以使用较慢的Iterator解决方案

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;
}
Run Code Online (Sandbox Code Playgroud)