您的位置:首页 > 移动开发 > Objective-C

Guava学习笔记(3)--覆写Object的常用方法[翻译+学习笔记]

2012-06-30 17:43 633 查看
Java的Object是所有类的父类, 也有几个常用的需要覆写的方法, 比如equals, hashCode和toString.

每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这几个方法的工具类, 比如apache commons lang.

Guava也提供了类似的方式, 在JDK7也提供了和Guava类似的方法.

equals

equals是一个经常需要覆写的方法, 可以查看Object的equals方法注释, 对equals有几个性质的要求: 自反性reflexive, 对称性symmetric, 传递性transitive, 一致性consistent. 还有一个要求: 对于所有非null的值x, x.equals(null)都要返回false. (如果你要用null.equals(x)也可以, 会报NullPointerException)

当我们要覆写的类中某些值可能为null的时候, 就需要对null做很多判断和分支处理. 使用Guava的Objects.equal方法可以避免这个问题, 使得equals的方法的覆写变得更加容易, 而且可读性强, 简洁.

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类, 其中有类似的方法equals.

hashCode

要求equals返回true的值, hashCode也返回相同的值. 所以覆写equals方法, 一般都要覆写hashCode方法.

写一个hashCode本来也不是很难, 但是Guava提供给我们了一个更加简单的方法--Objects.hashCode(Object ...), 这是个可变参数的方法, 参数列表可以是任意数量, 所以可以像这样使用Objects.hashCode(field1, field2, ..., fieldn).非常方便和简洁.

JDK7新引入了Objects类, 其中有类似的方法hash.

toString

这个方法是用得最多的, 覆写得最多, 一个好的toString方法对于调试来说是非常重要的, 但是写起来确实很不爽. 幸好我们可以用eclipse的自动生成代码的功能, 也可以使用apache commons lang来自动生成(使用反射), 当然Guava也提供了方法.

// Returns "ClassName{x=1}"
Objects.toStringHelper(this)
.add("x", 1)
.toString();

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


commons lang的生成方式使用了反射, 效率可能会低一点, 但是有个好处, 修改了类中的成员变量, 不需要修改toString方法, 因为是用的反射. 这个还是很方便的.

compare/compareTo

实现Comparator或Comparable接口, 可以实现比较功能, 但是这个方法却并不好重写, 写过的人都知道. 为了简化, Guava提供了ComparisonChain.

ComparisonChain是一个lazy的比较过程, 当比较结果为0的时候, 即相等的时候, 会继续比较下去, 出现非0的情况, 就会忽略后面的比较.

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


下面是一个完整的示例, 展示了这几个方法的使用

import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering;

public class Person implements Comparable<Person> {
public String name;
public String nickname;
public Gender gender;

public Person(String name, String nickname, Gender gender) {
super();
this.name = name;
this.nickname = nickname;
this.gender = gender;
}

@Override
public int hashCode() {
return Objects.hashCode(name, nickname);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person that = (Person) obj;
return Objects.equal(name, that.name)
&& Objects.equal(nickname, that.nickname)
&& Objects.equal(gender, that.gender);
}
return false;
}
//	@Override
//	public String toString() {
//		return Objects.toStringHelper(this)
//				.add("name", name)
//				.add("nickname", nickname)
//				.add("gender", gender)
//				.toString();
//	}
@Override
public String toString() {
return Objects.toStringHelper(this)
.addValue(name)
.addValue(nickname)
.toString();
}

public String preferredName() {
return Objects.firstNonNull(nickname, name);
}

@Override
public int compareTo(Person that) {
return ComparisonChain.start()
.compare(this.name, that.name)
.compare(this.nickname, that.nickname)
.compare(this.gender, that.gender, Ordering.natural().nullsLast())
.result();
}

public static void main(String[] args) {
Person person = new Person("Jack", "Jackson", Gender.MALE);
System.out.println(person);
Person person2 = new Person("Jack", "Jackson", Gender.FEMALE);
System.out.println(person2.compareTo(person));
System.out.println(person2.equals(person));
}
}


因本人水平有限, 欢迎拍砖!

参考资料:

官方wiki: http://code.google.com/p/guava-libraries/wiki/GuavaExplained

Object common methods: http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: