Java集合架構源碼分析 - RandomAccess__Java

來源:互聯網
上載者:User

在JDK的源碼裡有一個RandomAccess介面,這個介面沒有任何方法需要實現,那麼它是幹什麼用的呢。

public interface RandomAccess {}

官方文檔解釋如下:

介面RandomAccess被List實現用來指示它們支援快速的(通常是恒定的)隨機訪問。此介面的主要目的是允許通用演算法改變其行為,以便在應用於隨機或順序訪問列表時提供良好的效能。
用於處理隨機訪問列表(如ArrayList)的最佳演算法可應用於順序訪問列表(如LinkedList)時產生二次行為。鼓勵通用列表演算法檢查給定列表是否是此介面的一個執行個體,然後應用演算法,如果將其應用於順序訪問列表將提供較差的效能,並在必要時更改其行為以保證可接受的效能。

認識到隨機訪問和順序訪問之間的區別通常是模糊的。例如,一些List實現在漸近線性訪問時間的情況下獲得巨大的訪問時間,但在實踐中訪問時間不變。這樣的List實現通常應該實現這個介面。作為一個經驗法則,如果對於典型的類執行個體,List實現應該實現這個介面。

根本原因是:

 for(int i = 0,n = list.size(); i <n; i ++)   list.get(ⅰ);

運行速度比這個迴圈更快:

for(Iterator i = list.iterator(); i.hasNext();)    i.next();

我自己的理解是這樣的。

容器一般情況下有兩種實現方式,一種是數組,一種是鏈表,對於數組來說,隨機訪問(下標訪問)是最快的,但是對於鏈表的實現形式來說,隨機訪問(下標訪問)是很慢的,因為需要從頭結點逐步訪問到對應的下標結點。

所以為了提高訪問效率,通過這個介面來區分是否當前類允許隨機訪問。

我們看下最常用的兩個類ArrayList和LinkedList的類聲明。
ArrayList:

public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{...}

LinkedList:

public class LinkedList<E>    extends AbstractSequentialList<E>    implements List<E>, Deque<E>, Cloneable, java.io.Serializable    {...}

ArrayList實現的其中一個介面就是RandomAccess,但是LinkedList沒有,所以ArrayList的隨機訪問效率要高,實際上也是這樣的,因為ArrayList是以數組儲存元素的。

Collection架構中的工具類Collections的binarySearch()方法就是藉助這個特性提高效能的。

public class Collections {    ...    public static <T>    int binarySearch(List<? extends Comparable<? super T>> list, T key) {        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)            return Collections.indexedBinarySearch(list, key);        else            return Collections.iteratorBinarySearch(list, key);    }    ...}

接著我們看下indexedBinarySearch和iteratorBinarySearch方法的源碼:
indexedBinarySearch

    private static <T>    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {        int low = 0;        int high = list.size()-1;        while (low <= high) {            int mid = (low + high) >>> 1;            //直接根據下標擷取元素值            Comparable<? super T> midVal = list.get(mid);            int cmp = midVal.compareTo(key);            if (cmp < 0)                low = mid + 1;            else if (cmp > 0)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found    }

iteratorBinarySearch

    private static <T>    int iteratorBinarySearch(List<? extends Comparable<? super T>> list, T key)    {        int low = 0;        int high = list.size()-1;        ListIterator<? extends Comparable<? super T>> i = list.listIterator();        while (low <= high) {            int mid = (low + high) >>> 1;            //根據迭代器尋找元素            Comparable<? super T> midVal = get(i, mid);            int cmp = midVal.compareTo(key);            if (cmp < 0)                low = mid + 1;            else if (cmp > 0)                high = mid - 1;            else                return mid; // key found        }        return -(low + 1);  // key not found    }

indexedBinarySearch方法是以下標的形式訪問元素,而iteratorBinarySearch是以迭代器的形式訪問,符合我們之前的結論。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.