本著針對面試,不負責任的態度,寫下《面試總結》系列。本系列記錄面試過程中各個知識點,而不是入門系列,如果有不懂的自行學習。
暢所欲言,歡迎來噴。
轉載請標明出處,本文地址:http://www.lxweimin.com/p/b7f28817bad1
面試中經常會問到這類問題。如下:
String s1="123";
String s2="123";
String s3=new String("123");
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s1.equals(s2));
- 兩個類對象的hashCode相等,對象相等嗎?equals相等,對象相等嗎?
以上兩種算是一類問題。
首先,要說1中==操作的問題,對String賦值,而非new出來的對象,這類值通常會存放在常量池中,不會在堆中創建對象,所以s1與s2指向的是同一個地址。s3是new出來的,那么會在堆中創建對象,在s3指向的是堆中的地址,所以s1==s3比較的是地址。
其次,equals操作,由于String類中重寫了equals方法,而Object類中的equals方法是直接做的==比較。
//Object.java
public boolean equals(Object obj) {
return (this == obj);
}
String類中重寫了equals()方法
//String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.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;
從源碼中可以看到,先從==判斷,這個判斷的是引用,如果不想等,接下來是循環字符串,判斷的字符串里面的內容,如果每個字符都相等,兩個String對象才相等。
從String類引申出來,我們能不能直接說==判斷的是對象的地址,equals()判斷的是對象的內容呢?
答案是不可以
,那么為什么呢?
==判斷的是兩個對象的地址,這個毋庸置疑,但是equals()這個是不確定的。
我們知道equals()方法是Object中的,也就是說,所有的對象都可以去覆蓋重寫該方法。沒有重寫equals()的時候,默認的equals()方法,等價于==方法。如果像String中那樣,每個類都有自己的邏輯,自定義個類,重寫equals()方法,恒返回true,那么怎么能夠判斷出來對象是相等呢?或者如學生類,重寫equals()的時候,判斷學生的姓名,年齡,性別,學號相等,那么返回true,這個也是符合自己的邏輯,但不能說明兩個類對象是相等的。
hashCode跟equals又是什么關系
默認的Object中的hashCode()是用的native層,得到一個hash值。
public native int hashCode();
類沒有重寫hashCode方法,那么類對象equals比較的時候,跟hashCode沒有任何關系。
重寫了hashCode()方法。
a. equals相等的兩個對象,hashCode()得到值一定相等
b. hashCode值相等的兩個對象,equals不一定相等。
b)中的情況,可以從HashMap等使用hash值的集合中得到結果。當hash值相等的時候,說明發生了hash沖突。
重要的事情
在決定重寫hashCode()方法的時候,一定要做到規范,有含義,不然如果在對象添加到HashMap等集合中發生沖突的概率會大大提高。