Java中hashCode()方法以及HashMap()中hash()方法
Java的Object類(lèi)中有一個(gè)hashCode()方法:
public final native Class<?> getClass(); public native int hashCode(); public boolean equals(Object obj) { return (this == obj); } public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }hashCode()是一個(gè)native方法,意味著方法的實(shí)現(xiàn)和硬件平臺(tái)有關(guān),默認(rèn)實(shí)現(xiàn)和虛擬機(jī)有關(guān),對(duì)于有些JVM,hashCode()返回的就是對(duì)象的地址,
大多時(shí)候JVM根據(jù)一定的規(guī)則將與對(duì)象相關(guān)的信息(比如對(duì)象的存儲(chǔ)地址,對(duì)象的字段等)映射成一個(gè)數(shù)值,并返回。
例如:HotSpot JVM中生成hash實(shí)現(xiàn):hotspot/src/share/vm/runtime/synchronizer.cpp在Java中,hashCode()方法的主要作用是為了配合基于散列的集合(HashSet、HashMap)一起正常運(yùn)行。當(dāng)向集合中插入對(duì)象時(shí),調(diào)用equals()逐個(gè)進(jìn)行比較,這個(gè)方法可行卻效率低下。因此,先比較hashCode再調(diào)用equals()會(huì)快很多。下面這段代碼是java.util.HashMap的中put方法的具體實(shí)現(xiàn):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;}?indexFor()源碼如下:
static int indexFor(int h, int length) { return h & (length-1); }因?yàn)閔ashMap要求Entry數(shù)組長(zhǎng)度必須為2的冪(hashMap默認(rèn)值為16,hashTable沒(méi)有這個(gè)要求,默認(rèn)值為11),
所以上述代碼就是取h的低4位作為Entry數(shù)組的下標(biāo)。由于覆蓋equals()需要覆蓋hashCode(),
所以hashCode()有時(shí)并不十分完美,比如只和高位有關(guān)等等,因此需要再次hash()一下。
hash()方法在JDK1.7中如下:
static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4); }這樣設(shè)計(jì)保證了對(duì)象的hashCode的32位值只要有一位發(fā)生改變,整個(gè)hash()返回值就會(huì)改變,高位的變化會(huì)反應(yīng)到低位里。
具體分析參考:http://www.iteye.com/topic/709945
https://www.zhihu.com/question/20733617
hash()方法在JDK1.8中如下:
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }?這樣設(shè)計(jì)保證了對(duì)象的hashCode的高16位的變化能反應(yīng)到低16位中,相比較而言減少了過(guò)多的位運(yùn)算,是一種折中的設(shè)計(jì)。
總結(jié)
以上是生活随笔為你收集整理的Java中hashCode()方法以及HashMap()中hash()方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 163邮箱被盗怎么找回?
- 下一篇: TP-LINK TL-WR842+ 无线