java中所有的类都继承了Object类,当有需求时, 会重写equals, hashCode, toString方法,guava提供了Objects类简化了这些操作
1 equals
jdk要求对equals的重写要符合一下几点:
1. 自反性reflexive:任何非空引用x,x.equals(x)返回为true;
2. 对称性symmetric:任何非空引用x和y,x.equals(y)返回true当且仅当y.equals(x)返回true;
3. 传递性transitive:任何非空引用x和y,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true;
4. 一致性consistent:两个非空引用x和y,x.equals(y)的多次调用应该保持一致的结果,(前提条件是在多次比较之间没有修改x和y用于比较的相关信息);
5. 对于所有非null的值x, x.equals(null)都要返回false。 (如果你要用null.equals(x)也可以,会报NullPointerException)。
基于以上要求可知,当我们要重写equals方法时,要进行非空判断, guava的Objects提供了equal方法,可支持参数为null的判断,判断的是否相等的已经还是根据对象的equals方法,只不过在
Objects的equal方法里做了null的判断
下面是一个demo
class User {
private String username;
private String sex;
public User (String username, String sex) {
this.username = username;
this.sex = sex;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (sex != null ? !sex.equals(user.sex) : user.sex != null) return false;
if (username != null ? !username.equals(user.username) : user.username != null) return false;
return true;
}
@Override
public int hashCode() {
return Objects.hashCode(this.getUsername(), this.getSex());
}
@Override
public String toString () {
return Objects.toStringHelper(this.getClass()).add("username", this.getUsername())
.add("sex", this.getSex())
.toString();
}
public User () {
}
void setUsername(String username) {
this.username = username;
}
void setSex(String sex) {
this.sex = sex;
}
String getUsername() {
return username;
}
String getSex() {
return sex;
}
}
public static void main (String[] args) {
System.out.println(Objects.equals(null, null));
System.out.println(Objects.equals("a", null));
System.out.println(Objects.equals(null, "a"));
System.out.println(Objects.equals("a", "a"));
User u1 = new User("malone", "man");
User u2 = new User("malone", "man");
System.out.println(Objects.equals(u1, u2));
System.out.println(Objects.equals(u1, u1));
System.out.println(Objects.equals(u1, u2));
System.out.println(Objects.hash(null, null));
System.out.println(Objects.hash(null, null));
System.out.println(Objects.hash(u1, u2));
}
2 hashCode方法:
由于jdk约定两个对象equals返回true,那么他们的hashCode也应该相同,当我们去重新hashCode的时候总不知道怎么写好,guava的Objects提供了hashCode方法,支持多个对象输入,
以上面的User类来说,我们重写了equals方法,只要用户名和性别相同,那么两个对象就相同,我们这里可以这样重写hashCode,保证equals返回true时,hashCode返回的值相同
@Override
public int hashCode() {
return Objects.hashCode(this.getUsername(), this.getSex());
}
3 toStringHelper
重写toString方法很别扭,想体现对象多个属性的值,Objects提供了一个toStringHelper方法来简化这个操作:
@Override
public String toString () {
return Objects.toStringHelper(this.getClass()).add("username", this.getUsername())
.add("sex", this.getSex())
.toString();
}