1. ==
Java中分两类数据类型:基本数据类型
boolean,byte,char,short,int,long,float,double
和类对象(的引用)。
a. 对于基本类型的==判断的是它们的值是否相等。
b. 对于对象(的引用)则判断的是它们是否指代同一个对象。例如:
A a = new A();
A b = a;
a == b; //true
A c = new A();
A d = new A();
c == d;//false
2.equals
boolean equals(Object o)方法继承自java.lang.Object类中,其中对它的实现默认如下:
public boolean equals(Object obj){
return (this == obj)
}
可以看到通常equals方法是与==发挥同样的作用的。
一般为了功能需求会重写equals方法,通常重写的流程如下:
if(this == obj)
return true; // 如果指向同一对象,则为true
if(obj instanceof ClassName){//className 为该类的类名
ClassName obj1 = (ClassName)obj;
//此处比较类中各域(属性)的值是否相等,相等返回true
}
return false;
在这种情况下,equals方法发挥了真正比较两个对象的值是否相等的作用。
通常equals方法有以下特性(了解即可):
a.自反性:x.equals(x)
一定为true。
b.对成性:x.equals(y) == true,y.equals(x) == true
。
c.传递性:x.equals(y) == true,y.equals(z) == true,则x.equals(z) == true
。
d.一致性:如果参与比较的对象都没有改变,则比较的结果也不发生改变。
e.非空性:x.equals(null)
一定为false。
3.hashCode
public native int hashCode()
方法返回一个基于对象的物理地址按照特定的hash算法计算出的一个哈希值。对于一个哈希算法(f=h(x)
)总是会出现以下性质:
a. 如果 a = b,则一定h(a) = h(b)
b. 如果 a != b,则可能会出现h(a)=h(b)
按照以上原理可知:
a. 同一个对象多次调用返回的都是同一个值
b. 如果a.equals(b)
,则一定有a.hashCode()等于b.hashCode()
c. 如果 !a.equals(b)
,则a.hashCode()不一定等于b.hashCode()。(如果这两者的hash值总是不相等则说明该哈希算法效率比较高)
d. 如果a.hashCode()
不等于b.hashCode()
,则a.equals(b)为假。
(以上是在不重写equals方法的基础上得出的结论)
因此,如果要重写equals方法,通常需要重写hashCode方法来保证二者满足以上的性质。
//源自jdk,java.lang.Object类中给出的解释。
以下给出jdk中java.lang.String类中对hashCode()方法的重写以及对equals方法的重写示例:
public boolean equals(Object obj){
if(this == obj)
return true;
if(obj instanceof String){
String anotherObject = (String)object;
int n = value.length;//value是char数组
if(n == anotherObject.length()){
char[] v1 = value;
char[] v2 = anotherString.value;
int i = 0;
while(n-- !=0 ){
if(v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
public int hashCode(){
int h = hash;//private int hash;对象初始化的时候为哈希cache初始化为0;
if(h == 0 && value.length > 0){
char[] val = value;
for(int i = 0;i<value.length;i++){
h = 31 * h + val[i];
}
hash = h;
}
return h;
}