(Guava 译文系列)通用Object方法

通用Object方法

equals

假如你的对象成员变量可以为 null,那么实现 Objec.equals将会很痛苦,因为你得单独检查null的情况。使用Objects.equal可以让你采用 null 敏感的检查方式来实施equals,且不存在抛出NullPointerException的风险。

1
2
3
4
Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true

注意:JDK7 中新引入的类Objects提供了相同的实现Objects.equals

hashCode

对一个Object中所有成员变量的哈希应当更为简单。Guava 的Objects.hashCode(Object...)为指定序列的成员变量创建了明智的、顺序敏感的哈希。使用Objects.hashCode(field1, field2, ..., fieldn)来替代手工构建哈希。

注意:JDK7 中新引入的类Objects提供了相同的实现Objects.hash(Object...)

toString

一个优秀的toString方法会对 debug 产生难以估量的价值,然而他写起来很痛苦。使用MoreObjects.toStringHelper()来简单地创建一个实用的toString。以下包含一些简单的示例:

1
2
3
4
5
6
7
8
9
// Returns "ClassName{x=1}"
MoreObjects.toStringHelper(this)
.add("x", 1)
.toString();

// Returns "MyObject{x=1}"
MoreObjects.toStringHelper("MyObject")
.add("x", 1)
.toString();

compare/compareTo

实现一个Comparator,或者直接实现Comparable接口,会很痛苦。参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person implements Comparable<Person> {
private String lastName;
private String firstName;
private int zipCode;

public int compareTo(Person other) {
int cmp = lastName.compareTo(other.lastName);
if (cmp != 0) {
return cmp;
}
cmp = firstName.compareTo(other.firstName);
if (cmp != 0) {
return cmp;
}
return Integer.compare(zipCode, other.zipCode);
}
}
上面的代码很容易搞混,难以查找 bug 且存在令人难受的冗余。我们应当做的更好才对。

据以上目标,Guava 提供了ComparisonChain

ComparisonChain 实现了“懒比较”:他只执行比较,直到发现了非零的结果,然后忽略进一步的输入。

1
2
3
4
5
6
7
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}

这种流式语法更易读,不容易出现意外的打字错误,并且足够聪明到除非必须否则不做任何额外的工作。更多的与比较相关的实用工具可以在 Guava 的“流式比较器”类Ordering中找到,可在这里找到详细解释。