Hash(4) hashtable,hashmap
?
首先,我們要知道set是利使用map是實現的,因為只要利用map中的key唯一性就行了。
1.hashmap 和hashtable的區別是什么?
我們可以背出:? hashtable線程安全。hashmap不安全。
??????????????????????? hashmap中key 和value可以為空,當然根據唯一性,只能有一個key為null;
?????????????????????? 還有呢,hash函數不同下面再談)
2.我們在知識點回顧中,對于一個hash函數,有哪些方法,如何解決沖突/
?除留余數法(最常用),平方取中,隨機數法
開放地址法,拉鏈法
3、那么hashmap中和hashtablehash函數是什么呢?如何解決沖突的呢。
解決沖突是拉鏈法,就是加鏈表。
那么hash函數呢,
hashmap 比較高級,我們看hashmap,如果你復習一下數據結構,在哈希表中,他會告訴你,一個hash表就是個數組,這個數組有大小,同時還有裝載因子,
size*loadFactor就是我們能存元素個數的最大值,這個值叫做閾(yu)值,超過這個值,就會resize,意思就是重新擴張數組,然后對老元素重新hash,所以resize很費時。
hashmap在size上下了功夫,他把數組的大小設置為2的n次方,初始為16.,如果不夠用就成2倍擴張。為什么設置為2的n次方呢?
這樣可以充分利用位運算的優勢。比如 a*2? 表示成? a<<1,?那么 a%16=a&1?5=a&(1111)=a的二級制的后面4為,在位圖中我們a%32=a&31
其實如果我們看 a&1=a%2? a&3=a%4? 好了,下面我們看看它的hash函數吧
static int indexFor(int h, int length) {return h & (length-1);}?看到沒有直接風騷的使用h&(length-1)而且length是2的倍數。其實就是h%(length)
慢著,這個函數有什么缺陷呢?當size比較小的時候,比如32的時候,也就是(11111),最后根據key確定位置的時候,是根據key的后5位確定的,而key,函數中使用h表示,是int型啊,32位的數只能通過后五位確定,這樣沖突會很多,我們希望32位的每一位都被考慮進來。都可以決定key的位置,于是,
1 static int hash(int h) { 2 // This function ensures that hashCodes that differ only by 3 // constant multiples at each bit position have a bounded 4 // number of collisions (approximately 8 at default load factor). 5 h ^= (h >>> 20) ^ (h >>> 12); 6 return h ^ (h >>> 7) ^ (h >>> 4); 7 }我們看到了,這個復雜的代碼,它的意思就是我剛才說的,通過移位和異或讓更多的位決定key的位置,這樣會減少沖突,更均勻。
但是hashtable,雖說是線程安全的,但是他是jdk1.0引入的很老,它的hash函數很普通,
int?index?=?(hash?&?0x7FFFFFFF)?%?tab.length; //hash就是key的hashcode,然后獲得非符號位(hashcode為 int,可能為負,所以去掉符號位);
對于線程安全,以后再仔細說。
?
?
?
?
?
?
?
?
?
?
?
?
?
http://zhangshixi.iteye.com/blog/672697
?
???????????????
?
轉載于:https://www.cnblogs.com/hansongjiang/p/3836750.html
總結
以上是生活随笔為你收集整理的Hash(4) hashtable,hashmap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 问题与解答 [Questions A
- 下一篇: 借入单的后续处理-借入归还