我們知道hash演算法的目的在於,讓我們儲存的值更更更加散散散列的儲存資料;
那要分析這個hash演算法那就離不開定址演算法了,hashmap怎麼決定儲存位置的?
這是hashmap的put方法,我們可以發現hashmap的定址演算法:
(length - 1) & hash //決定值的儲存位置index
hashmap的length是2的n次冪length可能的值:2/4/8/16…
因為有&運算,我們轉換成二進位制:
( 2-1) :0000 … 0001
( 4-1) :0000 … 0011
( 8-1) :0000 … 0111
(16-1):0000 … 1111
…&運算的結果是都為1,結果才是1;
例子:hash & (16-1)
1010 1010 1001 1111 0000 0110 1100 0011
0000 0000 0000 0000 0000 0000 0000 1111
結果: 0000 … 0011
hash &(length -1)的結果就是只會保留(length - 1)的低位資料,而且是不會大於(length -1);
這樣就有效的控制了定址演算法的值剛好在我們定義的length範圍內。
這也是為什麼hashmap保證length是2的n次冪的原因
static final int hash(object key)
直接看hash()的原始碼
拿到hashcode了為什麼還要右移16位?還做了一次^運算?hashmap是可以存key=null;
從**看key==null的時候預設決定了位置index=0
hashmap是陣列+鍊錶;值的注意的是,null只是儲存在陣列index為0的位置,而具體在鍊錶的哪個位置是不確定的。
hashcode:乙個32位的int值我們假想一種情況:
有沒有可能我們儲存的值的key的hashcode大部分都是1在高位
例如:1011 0000 … 0000
1000 0000 … 0000
0011 0000 … 0000
…定址演算法又是取得hash值的低位資料 ===》 這導致乙個結果就是高位資料集中在index=0;
這應該不會有人覺得這結果符合雜湊的要求吧?
為什麼要》16?定址演算法導致的結果是index位置是hash值的低位決定,那高位豈不是沒了參與感?那就讓高位也有參與感:
1、把hashcode右移16位,這樣高位的16位資料平移到了低位;
2、高16位平移後和低16位做一次運算,這不就都參與了?
解決了》問題,那為什麼要用^,而不是&或者|?&:都為1則為1 ==》 有0就為0,結果更偏向於0
|:有1則為1 ==》 結果更偏向於1
^:相同為0,不同為1 ==》 …
JDK8中LocalDate的方法
getyear int 獲取當前日期的年份 getmonth month 獲取當前日期的月份物件 getmonthvalue int 獲取當前日期是第幾月 getdayofweek dayofweek 表示該物件表示的日期是星期幾 getdayofmonth int 表示該物件表示的日期是這個月第幾...
jdk8學習總結
今天抽點時間對jdk8寫個總體的學習總結,一來當作乙個覆盤加深理解,二來也希望能夠對閱讀的朋友們有一點點幫助,同時也希望大家對文中不準確的內容予以指出。1 函式式介面與lambda表示式 首先說一下函式式介面的概念 介面中的抽象方法如果是重寫了object類的方法的話,是不參與計數的 另外如果乙個介...
JDK8中Optional的方法使用
1.optional.of 或者optional.ofnullable 建立optional物件,差別在於of不允許引數是null,而ofnullable則無限制。test public void testoptional 2.ispresent 判斷值是否存在 ispresent判斷值是否存在 s...