在Map中實現key唯一不重復操作
Map中如何實現key唯一不重復
問題:如何做到Map中key唯一不重復,每次都遍歷來equals比較嗎?
首先,答案是否。如果全部遍歷的話,當Map中元素很多的時候,顯然查詢效率低。
解釋: HashMap屬於散列存儲結構,其table的存儲是放在不同的Jvm內存區域。通過一個整型值來標識table的區域,相當於這個區域的下標。然後整個查找過程就從不再需要遍歷整個table,隻需遍歷這一區域的數據即可。
結合HashMap.class中的put方法來說明:
如何找到這個區域呢?
1.首先將傳入的key值用hash方法轉化為int型的hash值,並且通過該方法讓hash值變得各位更均勻一些。變得更均勻的目的是讓每一個區域的大小更加等分些,公平利用存儲空間,查詢速度得到提升。
2.而後的indexfor方法將根據其hash值和table的大小得到這個區域的“位置下標”。具體其方法的實現同樣也是為瞭讓各個區域分佈的更加均勻。
得到這個區域以後,再遍歷這個區域來找到對應的元素
1.通過for循環遍歷這個區域的鏈表,在循環中如果key值的hash值相等,並且其key值相等,那麼進行覆蓋原元素操作。
2.如果遍歷結束依然沒找到,則新添元素
Map放入相同的key值
因為Map本身是不可以放相同的key的,但是如果我們想,也是有辦法的。
另外java也給我們提供瞭一個鉆空子的方法,這就是JDK1.8的IdentityHashMap,也是Map的一個實現類
HashMap比較key的值是用equals來比較的,所以隻要key的值一樣,就會被認為是同一個key。而IdentityHashMap是用==來比較key的存放地址,所以,隻要我們重新new出來一個對象,就可以把值相同的key定義為值相等但地址不相同的key,這樣就不會被認為是同一個key
public class MapTest { public static void main(String[] args) { Map map = new IdentityHashMap(); map.put(new Integer(1), "tom"); map.put(new Integer(1), "ben"); map.put(new Integer(1), "cat"); map.put(new Integer(1), "dog"); System.out.println(map); } }
輸出結果是:
{1=tom, 1=dog, 1=cat, 1=ben}
另外HashMap還可以自己重寫hashCode和put來實現hashCode的值不一樣,從而不會被認為是同一個key,繼續研究。。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- HashMap實現保存兩個key相同的數據
- java map中相同的key保存多個value值方式
- 搞懂JAVAObject中的hashCode()
- Java基礎之淺談hashCode()和equals()
- 淺談java中為什麼重寫equals後需要重寫hashCode