Java8對許多內置的容器進行了優化與拓展,其中對HashMap的改變尤其大。之后將進行總結。
最近在看HashMap的源碼時,發現了里面好多很不錯的算法,相比Java7從性能上提高了許多。其中tableSizeFor就是一個例子。tableSizeFor的功能(不考慮大於最大容量的情況)是返回大於輸入參數且最近的2的整數次冪的數。比如10,則返回16。該算法源碼如下:
static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
詳解如下:
先來分析有關n位操作部分:先來假設n的二進制為01xxx...xxx。接着
對n右移1位:001xx...xxx,再位或:011xx...xxx
對n右移2為:00011...xxx,再位或:01111...xxx
此時前面已經有四個1了,再右移4位且位或可得8個1
同理,有8個1,右移8位肯定會讓后八位也為1。
綜上可得,該算法讓最高位的1后面的位全變為1。
最后再讓結果n+1,即得到了2的整數次冪的值了。
現在回來看看第一條語句:
int n = cap - 1;
讓cap-1再賦值給n的目的是另找到的目標值大於或等於原值。例如二進制1000,十進制數值為8。如果不對它減1而直接操作,將得到答案10000,即16。顯然不是結果。減1后二進制為111,再進行操作則會得到原來的數值1000,即8。
這種方法的效率非常高,可見Java8對容器優化了很多,很強哈。其他之后再進行分析吧。