在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法。 Guava也提供了提供了覆写这几个方法的工具类。
equals方法的介绍
equals是一个经常需要覆写的方法, 可以查看Object的equals方法注释, 对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)。
在使用Guava的ComparisonChain进行比较时,应该注意到ComparisonChain是一个lazy的比较过程, 当比较结果为0的时候, 即相等的时候, 会继续比较下去, 出现非0的情况, 就会忽略后面的比较。ComparisonChain实现的compare和compareTo在代码可读性和性能上都有很大的提高。
hashCode方法的介绍
当覆写(override)了equals()方法之后,必须也覆写hashCode()方法,反之亦然。这个方法返回一个整型值(hash code value),如果两个对象被equals()方法判断为相等,那么它们就应该拥有同样的hash code。Object类的hashCode()方法为不同的对象返回不同的值,Object类的hashCode值表示的是对象的地址。
Guava提供给我们了一个更加简单的方法–Objects.hashCode(Object …), 这是个可变参数的方法,参数列表可以是任意数量,所以可以像这样使用Objects.hashCode(field1, field2, …, fieldn)。非常方便和简洁。
对象的比较
通过实现Comparable和Comparator接口来实现.
测试代码
Student.java
public class Student implements Comparable<Student> {
private int age;
private String name;
private float score;
public Student() {
}
@Override
public int hashCode() { // 重写hashCode方法
return Objects.hashCode(age, name, score);
}
@Override
public boolean equals(Object obj) { // 重写equals方法
if (this == obj)
return true;
if (obj == null)
return false;
if (obj instanceof Student) {
Student that = (Student) obj;
return Objects.equal(name, that.name) //
&& Objects.equal(age, that.age) //
&& Objects.equal(score, that.score);
}
return false;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
@Override
public int compareTo(Student other) { // 重写比较方法
return ComparisonChain.start().//
compare(age, other.age).compare(name, other.name).//
compare(score, other.score, Ordering.natural().nullsLast()).// nullsLast,表示null放到no-null的后面
result();//
}
}
StudentComparator.java
class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return ComparisonChain.start()//
.compare(s1.getName(), s2.getName())//
.compare(s1.getAge(), s2.getAge()).//
compare(s1.getScore(), s2.getScore())//
.result();
}
}
TestObjects.java
public class TestObjects {
public static void main(String[] args) {
Student student0 = new Student("p", 23, 80);
Student student1 = new Student("a", 23, 36);
Student student2 = new Student("j", 24, 90);
Student student3 = new Student("p", 23, 80);
System.out.println("==========equals===========");
System.out.println(student0.equals(student2));
System.out.println(student0.equals(student1));
System.out.println(student0.equals(student3));
System.out.println("==========hashCode===========");
System.out.println(student0.hashCode());
System.out.println(student1.hashCode());
System.out.println(student3.hashCode());
System.out.println(student2.hashCode());
System.out.println("==========compareTo===========");
System.out.println(student0.compareTo(student1));
System.out.println(student0.compareTo(student2));
}
}
测试结果
==========equals===========
false
false
true
==========hashCode===========
125834309
1201205425
125834309
-44346599
==========compareTo===========
1
-1