Object的equals方法比较常用,但它比较的是两个对象的引用是否相同,一般情况下,都需要我们重写equals方法。重写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。
equals方法的重写都老生常谈了,就不记了。。。。
重写equals方法,要重写hashCode方法。为什么呢?
首先,这是一个规定:
equals方法相等的两个对象,那么它们的hashCode也相等。但hashCode相等的两个对象,equals不一定相等。
虽然说一般的对象比较只会跟equals方法有关,但跟散列(Hash)有关的对象就需要用到HashCode这个属性了,比HashTable,HashSet.
HashSet中,判断两个对象是否相等,先判断HashCode是否相等,接着才判断equals方法是否相等。重写了hashCode,就避免了重复的可能,更好的兼容散列对象。
如何重写hashCode?
一般是这样:
public int hashCode() {
2. int result = 17; //任意素数
3. result = 31*result +c1; //c1,c2是什么看下文解释
4. result = 31*result +c2;
5. .....
6. result = 31*result + cn; //有多少个比较属性就多少
7. return result;
8.}
其中c1,c2...cn是要计算在内的字段的代码,生成规则如下:
如果字段是boolean 计算为(f?1:0);
如果字段是byte,char,short,int则计算为 (int)f;
如果字段是long 计算为 (int)(f^(f>>32));
如果字段是float 计算为 Float.floatToLongBits(f);
如果字段是一个引用对象,那么直接调用对象的hashCode方法,如果需要判空,可以加上如果为空就返回0;
如果字段是一个数组则需要遍历所有元素,按上面几种方法计算;
具体例子见下面代码:
private String name ;
private String noMean; //这个属性没用到,所以hashCode方法中没出现
private int age;
private long id;
private float height;
private char sex;
private double weight;
private byte key;
private short value;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + Float.floatToIntBits(height);
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + key;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
result = prime * result + value;
long temp;
temp = Double.doubleToLongBits(weight);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
当然啦,直接用编辑器如eclipse也是可以自动重写hashCode和equals方法的。。。。。