中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android 特有的數據結構SpareArray 詳解

發布時間:2020-06-06 13:23:50 來源:網絡 閱讀:4269 作者:poarry 欄目:移動開發

android developer 的開發文當中是這么描述SparesArray的:

SparseArrays map integers to Objects. Unlike a normal array ofObjects, there can be gaps in the indices. It is intended to be more efficientthan using a HashMap to map Integers to Objects.

大概意思是SparseArrays是映射Integer—> Objects 類型的,就像這樣: SparseArrays< Object>而且在指數級別的數量的增長上來說和HashMap相比較的話,性能方面SparseArrays更好。

  

為什么會突然說SparseArrays呢?因為我在看Activity源碼的時候看到了這段代碼:

privatestaticclassManagedDialog {

        Dialog mDialog;

        Bundle mArgs;

   }

private SparseArray<ManagedDialog> mManagedDialogs;

我不知道SparseArray是什么,然后點進去繼續看這個類的實現,和開始介紹

/**

 * SparseArrays map integers to Objects.  Unlike a normal array of Objects,

 * there can be gaps in the indices.  It is intended to be more memory efficient

 * than using a HashMap to map Integers toObjects, both because it avoids

 * auto-boxing keys and its data structure doesn'trely on an extra entry object

 * for each mapping.

 **/

前半段和上面api文檔上介紹的一樣,后半段的意思就是因為數據結構的實體類不依賴外在實體并且避免了自動裝箱時候的key,所以效率更高。(效率高的另外一個原因我們等下再說)

我繼續回來看代碼發現在下面這段代碼中用到了SparseArray.

 

finalint[]ids = b.getIntArray(SAVED_DIALOG_IDS_KEY);

finalintnumDialogs = ids.length;

 mManagedDialogs = newSparseArray<ManagedDialog>(numDialogs);

    for(inti = 0; i < numDialogs; i++) {

        final Integer dialogId = ids[i];

         Bundle dialogState = b.getBundle(savedDialogKeyFor(dialogId));

       if (dialogState != null) {

         // Calling onRestoreInstanceState() below will invoke dispatchOnCreate

          // so tell createDialog() not to do it, otherwise we get an exception

                final ManagedDialog md = new ManagedDialog();

                md.mArgs = b.getBundle(savedDialogArgsKeyFor(dialogId));

                md.mDialog = createDialog(dialogId, dialogState, md.mArgs);

                if (md.mDialog != null) {

                    mManagedDialogs.put(dialogId, md);

                    onPrepareDialog(dialogId,md.mDialog,md.mArgs);

                    md.mDialog.onRestoreInstanceState(dialogState);

                }

          }

      }

上面這段代碼做的事情就是根據對話框id的個數來創建SparesArrays的大小。并且根據ManagedDialogiddialogState,也就是存dialog的狀態。說白了就是<Integer,Object>格式的HashMap

 

我回去繼續閱讀SparesArrays的源碼發現:

Android 特有的數據結構SpareArray 詳解

 

它的構造方法設置了默認大小為10

List一樣,獲取元素的方法有兩個如圖所示我們可以發現

public E get(int key)方法還是調用的public E get(int key, E valueIfKeyNotFound)。只是在找不到元素的時候設置了默認的返回值為null

值得注意的是,它查找的時候用的是二分查找(折半查找)算法,所以快。

Android 特有的數據結構SpareArray 詳解

感覺整個SparesArrays的核心就是binarySearch。我們看下它的源代碼:

static int binarySearch(int[] array, int size, intvalue) {

        int lo =0;

        int hi =size - 1;

        while(lo <= hi) {

           final int mid = (lo + hi) >>> 1;

           final int midVal = array[mid];

 

            if(midVal < value) {

               lo = mid + 1;

            }else if (midVal > value) {

               hi = mid - 1;

            }else {

               return mid;  // value found

            }

        }

        return~lo;  // value not present

    }

 

    static intbinarySearch(long[] array, int size, long value) {

        int lo =0;

        int hi =size - 1;

 

        while(lo <= hi) {

           final int mid = (lo + hi) >>> 1;

           final long midVal = array[mid];

 

            if(midVal < value) {

               lo = mid + 1;

            }else if (midVal > value) {

               hi = mid - 1;

            }else {

                return mid;  // value found

            }

        }

        return~lo;  // value not present

    }

 

再來看它刪除的時候有四種方法;

Android 特有的數據結構SpareArray 詳解

前三種中

public void delete(int key)是根據折半查找刪除,

public void remove(int key)調用的是delete(int key)

public void removeAt(int index)根據index刪除

public void removeAtRange(int index, int size)這個是調用publicvoid removeAt(int index)(上面截圖中沒有)

 

添加數據方法有public voidput(int key, E value)

Android 特有的數據結構SpareArray 詳解

在紅框中的代碼表示 put的時候會先查案當前的SparesArrays中是否存在此數據,如果存在那么就是修改這個數值,不會添加,如果沒有查找到那么久會添加。

還有一個方法是修改數組中的數值的

public void setValueAt(int index, Evalue)

Android 特有的數據結構SpareArray 詳解

如注釋中說的,會給index的位置的value進行修改。

public int keyAt(int index)這個方法是根據index來獲取key值。范圍是0-size-1.

Android 特有的數據結構SpareArray 詳解

同樣的public E valueAt(int index)就是根據index來獲取對應位置的object。如圖:

Android 特有的數據結構SpareArray 詳解

還有public void append(int key,E value)方法,這個方法是在key遠遠大于數組中所有的key的時候添加數據提高性能的方法,如果key>0 并且key小于等等數組中最后一個的key的情況下還是調用的put方法。

Android 特有的數據結構SpareArray 詳解

最后一個方法就是toString,也就是打印出整個數組的字符串。這個沒多大意思就不貼出代碼了。

 

另外 想要閱讀android源碼的一種方式可以戳這里:

http://poarry.blog.51cto.com/5970996/1630731

 

以上純屬個人見解,如有失誤,歡迎指正poarryScript@gmail.com


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宜良县| 乌拉特前旗| 云阳县| 安西县| 阜康市| 林芝县| 武穴市| 水城县| 沁源县| 通城县| 陆良县| 泗阳县| 韩城市| 东乌珠穆沁旗| 新宁县| 平谷区| 临邑县| 浮山县| 鄢陵县| 渝中区| 清徐县| 抚顺市| 乡宁县| 凯里市| 铜梁县| 那坡县| 海阳市| 武乡县| 措美县| 池州市| 吉木乃县| 江孜县| 石楼县| 施甸县| 连城县| 台湾省| 金门县| 金川县| 广灵县| 广丰县| 三穗县|