兩個原因
1.查詢和增加元素是使用的取模運算來找到陣列下標,而取模運算如果是對2的n次冪,那麼可以用&位運算子代替,效率比較高。
2.擴容的時候方便。
直接看原始碼就明白了,擴容的resize方法的引數是2*table.length(圖中是JDK7的原始碼),意味著每次擴容都是2倍擴容,擴容之後就需要進行資料遷移了。如果初始長度是2的n次冪,擴容就會減少資料的遷移次數。
舉個例子初始長度是16,擴容到32後。之前在1位置的節點,擴容之後之後只會遷移到1和17的位置,其實就是之前在i的位置,擴容之後只會在i和i+之前陣列的長度。
比如17,在陣列長度是16的時候,在1的位置,當擴容到32後,就會遷移到17的位置;
比如1,在陣列長度是16的時候,在1的位置,當擴容到32後,還在1的位置。
主要就是這個原因了。
順便提下原始碼裡就是你不設定為2的n次冪,也會幫你設定為2的n次冪,比如說你傳15,會幫你設定為16的,原始碼對應的方法是roundUpToPowerOf2。
兩個原因
1.查詢和增加元素是使用的取模運算來找到陣列下標,而取模運算如果是對2的n次冪,那麼可以用&位運算子代替,效率比較高。
2.擴容的時候方便。
直接看原始碼就明白了,擴容的resize方法的引數是2*table.length(圖中是JDK7的原始碼),意味著每次擴容都是2倍擴容,擴容之後就需要進行資料遷移了。如果初始長度是2的n次冪,擴容就會減少資料的遷移次數。
舉個例子初始長度是16,擴容到32後。之前在1位置的節點,擴容之後之後只會遷移到1和17的位置,其實就是之前在i的位置,擴容之後只會在i和i+之前陣列的長度。
比如17,在陣列長度是16的時候,在1的位置,當擴容到32後,就會遷移到17的位置;
比如1,在陣列長度是16的時候,在1的位置,當擴容到32後,還在1的位置。
主要就是這個原因了。
順便提下原始碼裡就是你不設定為2的n次冪,也會幫你設定為2的n次冪,比如說你傳15,會幫你設定為16的,原始碼對應的方法是roundUpToPowerOf2。