徹底明白equals和hashCode

2022-05-25 15:24:10 字數 2627 閱讀 4919

@test

public void test()

hashcode方法是通過一定的演算法得到乙個hash值,一般配合雜湊集合一起使用,如hashmap、hashset都是不可以存放重複元素的,那麼當容器中元素個數很多時,你要新增乙個元素時,難道乙個乙個去equals比較?當然這是可以的,但是難免效率很低,而hashmap和hashset的底層都是使用陣列+鍊錶的方式實現的,這樣有什麼好處呢,當乙個物件要加入集合,直接用hashcode進行一些運算得到儲存的陣列下標,再去陣列下標對應的鍊錶中乙個乙個元素比較(equals),這樣顯然減少了比較次數,提高了效率

那object的hashcode方法的預設實現是怎樣的呢?

public native int hashcode();
可以看到它是乙個本地方法,實際上object的hashcode方法返回是元素的位址(不同的虛擬機器可能不一樣,但hotspot的是)

class emp	}

@test

public void test2()

6659c656轉換成十進位制也就是1717159510

我們很多時候這樣使用hashmap

@test

public void test3()

額?不對呀,編號為01001的張三呢?而且我們知道new出來的string的hashcode是位址一定是不相同的,那麼為什麼後乙個張三還是把前乙個張三覆蓋了呢?

是因為string重寫了hashcode方法和equals方法

public int hashcode() 

hash = h;

} return h;

}public boolean equals(object anobject)

//判斷傳入的物件是不是string型別

if (anobject instanceof string)

return true;

}} return false;

}

那麼當我們使用自己的物件作為鍵時

@test

public void test4()

可以看到輸出的是null,這是為什麼呢,就是因為我們自定義的類沒有重新寫hashcode方法,get的時候新new出來的emp物件的hashcode(也就是位址)肯定和存的時候的hashcode不一樣,所以拿不到,所以當我們自定義的類要使用雜湊集合儲存時,一定要重寫equals方法和hashcode方法

為什麼當我們要使用自定義物件作為key存放在hashmap中時,一定要重寫equals和hashcode呢?

我們去看看hashmap底層是怎麼存鍵值對和得到值的

hashmap的put方法

public v put(k key, v value) 

//計算鍵的hash

static final int hash(object key)

final v putval(int hash, k key, v value, boolean onlyifabsent,

boolean evict)

//如果找到已存入元素的key和插入key的hash相同並且兩key位址相等或equals,那麼e就是要替換的元素

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;}}

v oldvalue = e.value;

if (!onlyifabsent || oldvalue == null)

//替換舊值

e.value = value;

afternodeaccess(e);

return oldvalue;}}

++modcount;

if (++size > threshold)

//插入後元素大小超過閾值進行擴容

resize();

afternodeinsertion(evict);

return null;

}

hashmap的get方法

public v get(object key) 

final nodegetnode(int hash, object key) while ((e = e.next) != null);}}

return null;

}

可以看到存的時候是通過hashcode得到hash再用hash得到存放下標,然後存入鍵值對

取的時候是通過hashcode得到hash再得到下標元素,下標元素再根據hash&&(位址相等||equals)得到鍵值對

說了這些再來說說object規範

當我們自定義類不需要充當key來在雜湊表中儲存物件時,equals和hashcode根本沒有關係,你也沒必要重寫hashcode方法

當我們會用自定義類充當key在雜湊表中存物件,這時候你一定要重寫equals和hashcode

徹底明白IP位址

通過ip位址和子網掩碼與運算計算相關位址 知道ip位址和子網掩碼後可以算出 1 網路位址 2 廣播位址 3 位址範圍 4 本網有幾台主機 例1 下面例子ip位址為192 168 100 5 子網掩碼是255 255 255 0。算出網路位址 廣播位址 位址範圍 主機數。一 分步驟計算 1 將ip位址...

徹底弄明白LDO

工作原理 ldo內部基本都是由4大部件構成,分別是分壓取樣電路 基準電壓 誤差放大電路和電晶體調整電路。分壓取樣電路 通過電阻r1和 r2對輸出電壓進行採集 誤差放大電路 將採集的電壓輸入到比較器反向輸入端,與正向輸入端的基準電壓 也就是期望輸出的電壓 進行比較,再將比較結果進行放大,電晶體調整電路...

徹底明白Java的IO系統

1b.接收鍵盤的輸入 bufferedreader stdin new bufferedreader new inputstreamreader system.in system.out.println enter a line system.out.println stdin.readline 2...