在Java中Object类是所有类的父类,其中有几个需要override的方法比如equals,hashCode和toString等方法。每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这几个方法的工具类, Guava也提供了类似的方式。下面我们来看看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)。
当我们要覆写的类中某些值可能为null的时候,就需要对null做很多判断和分支处理。 使用Guava的Objects.equal方法可以避免这个问题, 使得equals的方法的覆写变得更加容易, 而且可读性强,简洁优雅。
hashCode方法:
当覆写(override)了equals()方法之后,必须也覆写hashCode()方法,反之亦然。这个方法返回一个整型值(hash code value),如果两个对象被equals()方法判断为相等,那么它们就应该拥有同样的hash code。Object类的hashCode()方法为不同的对象返回不同的值,Object类的hashCode值表示的是对象的地址。
hashCode的一般性契约(需要满足的条件)如下:
1.在Java应用的一次执行过程中,如果对象用于equals比较的信息没有被修改,那么同一个对象多次调用hashCode()方法应该返回同一个整型值。应用的多次执行中,这个值不需要保持一致,即每次执行都是保持着各自不同的值。
2.如果equals()判断两个对象相等,那么它们的hashCode()方法应该返回同样的值。
3.并没有强制要求如果equals()判断两个对象不相等,那么它们的hashCode()方法就应该返回不同的值。即,两个对象用equals()方法比较返回false,它们的hashCode可以相同也可以不同。但是,应该意识到,为两个不相等的对象产生两个不同的hashCode可以改善哈希表的性能。
写一个hashCode本来也不是很难,但是Guava提供给我们了一个更加简单的方法--Objects.hashCode(Object …), 这是个可变参数的方法,参数列表可以是任意数量,所以可以像这样使用Objects.hashCode(field1, field2, …, fieldn)。非常方便和简洁。
toString()方法:
因为每个类都直接或间接地继承自Object,因此每个类都有toString()方法。这个方法是用得最多的, 覆写得最多, 一个好的toString方法对于调试来说是非常重要的, 但是写起来确实很不爽。Guava也提供了toString()方法。
compare/compareTo方法:
CompareTo:compareTo(Object o)方法是java.lang.Comparable
compareTo方法的通用约定与equals类似:将本对象与指定的对象停止比拟,如果本对象小于、等于、或大于指定对象,则分离返回正数、零、或正数。如果指定的对象类型无法与本对象停止比拟,则跑出ClassCastException。
对称性:实现者必须保证对全部的x和y都有sgn(x.compareTo(y)) == -sgn(y.compareTo(x))。这也暗示当且仅当y.compareTo(x)抛出异常时,x.compareTo(y)才抛出异常。
传递性:实现者必须保证比拟关系是可传递的,如果x.compareTo(y) > 0且y.compareTo(z) > 0,则x.compareTo(z) > 0。实现者必须保证x.compareTo(y)==0暗示着全部的z都有(x.compareTo(z)) == (y.compareTo(z))。