ArrayDeque中的取余
Java里有一個叫做Stack的類,卻沒有叫做Queue的類(它是個接口名字)。而當需要使用棧時,Java已不推薦使用Stack,而是推薦使用更高效的ArrayDeque;既然Queue只是一個接口,當需要使用隊列時也就首選ArrayDeque了(次選是LinkedList)。
ArrayDeque底層實際上是使用雙向隊列數組結構來實現的。那我們知道使用雙向隊列就不得不面臨一個問題,那就是取余,然而直接使用符號’%‘來進行取余在效率上是不高的。在這里ArrayDeque使用了一個非常好的方法,使用’&'符號,那么這個符號是如何發揮作用的呢?我們可以從源碼當中一探究竟。
public void addFirst(E e) {if (e == null)throw new NullPointerException();elements[head = (head - 1) & (elements.length - 1)] = e;if (head == tail)doubleCapacity(); }在addFirst函數中顯然取余是通過:(head - 1) & (elements.length - 1)來完成的。另外,這里是先添加元素,而后檢查擴容的,因為雙向隊列的數組中總有一個位置是沒有用到的,所以可以直接添加元素而后檢查擴容。回到我們的主題,在ArrayDeque中有一個規定:elements.length一定是2的指數。雖然我們可以在初始化的時候寫入一個大小,但是ArrayDeque會自動將初始化數組增大到2的指數,且最小為8。
我們以一個例子分析一下,假如elements.length=0x100(256);則elements.length-1=0xff(255);而head-1最小為-1(0xffffffff)時,(head - 1) & (elements.length - 1)=0xff;指向了數組的尾部,也就沒有越界。如果是addLast,tail+1的時候,最大為256(0x100)時,(tail + 1) & (elements.length - 1)=0;指向了數組頭部,其他也是類似的,完美解決了取余效率不高的問題。
總結來說就是如果是對2的指數取余的時候,我們可以用num&(2^x - 1)來提高取余效率,這種方法還使用在HashMap中;
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的ArrayDeque中的取余的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统中的零拷贝与java中的使用
- 下一篇: LinkedHashMap 实现缓存(L