equals方法
Object类中的equals方法用于检测一个对象是否等于另一个对象,即判断两个对象是否具有相同的引用。然而,经常需要检测两个对象状态的相等性。如果两个对象的状态相等,就认为两个对象是相等的。我们可以根据自己的需求重写equals方法。
Java语言规范要求equals方法具有闭包特性。
1)自反性:对于任何非空引用x,x.equals(x)应该返回true。
2)对称性:对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
3)传递性:对于任何引用x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
4)一致性:如果x,y引用的对象没有发生变化,那么反复调用x.equals(y)应该返回相同的结果。
5)对于任意非空引用x,x,equals(null)应该返回false。
getClass()方法返回一个对象所属的类,只有在两个对象属于同一个类时,这个值才可能相等。
OtherObject instanceOf(Object)方法比较OtherObject与Object类型是否有继承关系,即当OtherObject类型为Object类型或者Object类型的子类型时才返回true。
编写完美equals方法的建议:
1)显示参数命名为otherObject.
2)检测this与otherObject是否引用同一个对象:
if(this==otherObject)return true;
3)检测otherObject是否为null,如果为Null,返回false.
if(otherObject==null)return false;
比较this与otherObject是否属于同一个类。如果equals的语义在每个子类中都有所改变,用getClass()检测
if(!getClass()==otherObject.getClass())return false;
若所有子类都有一致的语义,用instanceof()检测
if(!otherObject.instanceOf(ClassName))return false;
4)将otherObject转换成相应的类类型变量
ClassName other=(ClassName)otherObject;
5)对需要比较的域进行比较,用==比较基本类型域,用equals()比较对象域。如果所有域相等,返回true,否则返回false;
return field1==other.field1 && field2.equals(other.field2).....
如果在子类中重新定义了equals,就要在其中包含调用super.equals(other)。
hasCode方法
散列码(hashCode) 是由对象导出的一个整数值。散列码是没有规律的。两个不同的对象的散列码基本上不会相同。
String类计算散列码算法
int hash=0;
for(int i=0;i<length();i++)
hash=31*hash+charAt(i);
hashCode()方法定义在Object类中,每个对象都有一个默认的散列码,其值为对象的存储地址。
字符串的散列码是由内容导出的,像StringBuffer类中没有定义hashCode方法,它的散列码是由Object类的默认hashCode方法导出的对象存储地址。
要判断两个对象是否相等,就要重写equals()方法,具体的实现网上很多。重写equals()方法一般都要重写HashCode()方法,这是为了提高存储效率,HashCode方法可以保
证相同的元素存储于相同的地址,理论上可以没有,但是如果没有,使用效率会大大降低。
实际上不重写的hashCode,编译器不会报错,一般情况下也不回出问题,只要你不用类似于Hashtable存放这些对象。
之所以要求hashcode和equals一致,主要考虑的还是Hashtable问题。