java基礎解析系列(十一)---equals、==和hashcode方法
目錄
- java基礎解析系列(一)---String、StringBuffer、StringBuilder
- java基礎解析系列(二)---Integer緩存及裝箱拆箱
- java基礎解析系列(三)---HashMap原理
- java基礎解析系列(四)---LinkedHashMap的原理及LRU算法的實現
- java基礎解析系列(五)---HashMap並發下的問題以及HashTable和CurrentHashMap的區別
- java基礎解析系列(六)---注解原理及使用
- java基礎解析系列(七)---ThreadLocal原理分析
- java基礎解析系列(八)--fail-fast機制及CopyOnWriteArrayList的原理
- 這是我的博客目錄,歡迎閱讀
==
- 基本數據類型==比較的是值
類型 | 字節數 |
---|---|
float | 4 |
double | 8 |
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
char | 2 |
boolean |
- 非基本數據類型,也就是引用型變量,==比較的是指向的內存地址
equals
- Object類的的equals方法內部是用==比較,也就是比較地址
public boolean equals(Object obj) {
return (this == obj);
}
- 而如果不同類會重寫equals方法,比如String內部的equals比較的字符串的內容是否一樣
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;
}
hashcode方法
作用
- 如果沒有hashcode方法,在往一個set(不允許重復)添加的元素的時候,那么就得將全部的元素檢查一遍equals,如果有hashcode方法,一個對象的hashcode會映射到一個位置,在這個位置檢查是否存在即可,所以不需要全部檢查。可以看看hashmap的put方法
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
- 從源碼可以看到,先通過hash值找到在table中的位置,然后再進行查找,這樣就減少了執行equals的次數
equals方法和hashcode方法
- equals方法返回true,hashcode一定相同
- equals方法返回flase,hahscoe不一定不同
修改了equals方法
- 前面已經了解過,Object的equals返回兩個對象的內存地址是否相同,而Object類的子類經常會重寫equals方法,比如兩個People對象,比較的不是兩個People對象的內存地址,而是比較name,age等屬性,只要name和age相同就認為是同一個對象
- 如果只重寫了equals而不重寫hashcode方法,下面進行測試
public static void main(String[] args) throws Exception {
HashMap hashMap=new HashMap<Person,Integer>();
Person p1=new Person("jiajun",18);
Person p2=new Person("jiajun",18);
System.out.println("這兩個對象在設置的時候應該是相同的");
hashMap.put(p1,666);
System.out.println("那么按照我們的設計思路,我們通過p2應該可以得到666");
System.out.println(hashMap.get(p2));
System.out.println("可是這時候輸出的卻是null");
}
class Person
{
String name;
int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if(this.getClass()!=obj.getClass())
{
return false;
}
People p = (People)obj;
return this.name.equals(p.name)
&& this.age == p.age;
}
}
- 從實驗結果可以看出,如果重寫了equals方法而不重寫hashcode方法容易出現問題
Effective java的建議
- 在程序執行期間,只要equals方法的比較操作用到的信息沒有被修改,那么對這同一個對象調用多次,hashCode方法必須始終如一地返回同一個整數
- 如果兩個對象進行equals比較是相等的,那么這兩個對象的hashcode方法必須返回相同的整數結果
- 如果兩個對象進行equals比較是不同的,那么這個兩個對象hahscode方法不一定返回不同的整數
我覺得分享是一種精神,分享是我的樂趣所在,不是說我覺得我講得一定是對的,我講得可能很多是不對的,但是我希望我講的東西是我人生的體驗和思考,是給很多人反思,也許給你一秒鍾、半秒鍾,哪怕說一句話有點道理,引發自己內心的感觸,這就是我最大的價值。(這是我喜歡的一句話,也是我寫博客的初衷)
作者:jiajun 出處: http://www.cnblogs.com/-new/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如果覺得還有幫助的話,可以點一下右下角的【推薦】,希望能夠持續的為大家帶來好的技術文章!想跟我一起進步么?那就【關注】我吧。