关于位运算
位运算就是二进制运算,我们知道计算机cpu运算最底层的物理实现,就是高低电平输入,抽象成数学符号就是二进制01输入。因此位运算对cpu来说是最高效的,因为我们用它的“母语”和它交流。
因此,juc库很多地方都有位运算的影子,就是为了提高效率,有的地方用得巧妙真是让人惊叹,让人大呼还能这样,既优雅又简洁,应了中国的那句老话,大道至简!
运用示例
给定一个整型容量initialCapacity,计算这个容量最近的2的n的数
initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1); initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++;
上述代码翻译成人类语言就是,给定一个数,我们从二进制的角度看这个数;比如8,它的二进制是1000;把它最高位1之后的其他位都变成1,然后加1;即1000 -> 1111,加1后变成10000,对应的十进制是16.
上面这段代码其实是摘自ArrayDeque的 allocateElements,其实它还考虑了溢出变成负数情况,就是二进制最高位是1的情况。
类似的还有jdk1.8 hash map的容量初始化修正计算,为啥cap要先减去1,为了使得输入刚好是2的n次方的数的容量不需要再修正,比如8,对应的二进制是1000,减去1后的二进制是0111,对应的十进制是7,用同样的算法,算出结果是8,和输入的8一致。
ArrayDeque双端队列head和tail计算
ArrayDeque,底层用数组作为双端队列使用;head指针从队列尾部向前移动;tail指针从队首向后移动。如果队列满,扩容2倍,重置head 和tail。addFirst方法,是头部插入代码elements[head = (head - 1) & (elements.length - 1)] = e;由于队列长度是2的n次方,那么2的n次方减一,二进制低位全部是1;head开始是0,0减1结果是-1,-1是负数,在计算机中用补码表示,就是二进制11111111111111111111111111111111;所以两者做与运算,就得到elements数组的最大index。因此addFirst永远是从elements的尾部向前插。
addLast方法反之。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。