1、sparsearray
上面這段話來自sparsearray類的宣告,重點關注一下: 與使用hashmap將integers對映到objects相比,它的記憶體效率更高,因為它避免了自動裝箱鍵,並且其資料結構不依賴於每個對映的額外條目物件。(這也是sparsearray的優點)
sparsearray包含三個主要成員變數:
private int mkeys;
private object mvalues;
private int msize;
其中,mkeys用於存放鍵key,mvalues用來存放值(泛型e)。msize為鍵值對的數量。
初始容量預設為10。
先看put方法:
public void put(int key, e value) else
if (mgarbage && msize >= mkeys.length)
mkeys = growingarrayutils.insert(mkeys, msize, i, key);
mvalues = growingarrayutils.insert(mvalues, msize, i, value);
msize++;
}}
put方法首先在mkeys陣列中通過二分查詢演算法,找到key在mkeys陣列中的索引 i,如果i>0,即已經存在乙個鍵值對,則直接覆蓋mvalues陣列中的值。如果i<0,即不存在該鍵值對,但是由於mkeys陣列是從小到大排好序的,-i為key需要插入mkeys陣列中的位置,並且mkeys和mvalues陣列還有剩餘空間並且-i索引位置的值為空,表示不需要擴容並且不需要資料遷移,則把key存放在mkeys陣列的-i索引位置,value存放在mvalues陣列-i索引位置。
public static long insert(long array, int currentsize, int index, long element)
long newarray = arrayutils.newunpaddedlongarray(growsize(currentsize));
system.arraycopy(array, 0, newarray, 0, index);
newarray[index] = element;
system.arraycopy(array, index, newarray, index + 1, array.length - index);
return newarray;
}
如果,當前mkeys陣列和mvalues陣列已滿,或者-i索引位置已經有值。則通過growingarrayutils.insert方法把key插入到-i索引位置,並將-i(包含)以後的key向後平移乙個單位來完成key遷移。如果mkeys陣列需要擴容,則呼叫growingarrayutils.growsize方法進行擴容
public static int growsize(int currentsize)
擴容規則為:當前容量不大於4時直接擴容到8,否則雙倍擴容,由於前面說過初始容量為10,所以都是雙倍擴容。擴容完成後,在完成上面的key遷移過程。
再看get方法
public e get(int key)
public e get(int key, e valueifkeynotfound) else
}
很簡單,直接通過二分查詢在mkeys陣列中找到對應的索引,如果索引存在則直接返回mvalues陣列中該索引下的值。否則返回null。
2、arraymap
int mhashes;
object marray;
int msize;
arraymap同樣也是三個重要成員變數:1,mhashes用於存放key物件的hashcode值,該值也按照從小到大的順序排序。2,marray用於存放key和value物件。具提存放策略稍後講。3,msize為key-value鍵值對的數量。同樣先看put方法
@override
public v put(k key, v value) else
if (index >= 0)
index = ~index;
if (osize >= mhashes.length)
if (mhashes.length > 0)
freearrays(ohashes, oarray, osize);
}if (index < osize)
if (concurrent_modification_exceptions)
}mhashes[index] = hash;
marray[index<<1] = key;
marray[(index<<1)+1] = value;
msize++;
return null;
}
從上面可以看出,put方法先判斷key是否為空,如果為空,則hashcode為0,否則獲取key的hashcode值,然後根據hashcode值在mkeys陣列中找到對應的索引index,如果index>=0,則在marray陣列中2*index索引位置存放key物件,2*index+1索引位置存放value物件。如果index<0,表示沒找到則-index為當前hashcode要插入到mkeys陣列中的位置。如果mhashes陣列需要擴容,則判斷當前msize是否大於等於8(base_size*2),如果是則擴容為原來的1.5倍,否則判斷msize是否大於等於4,如果是則擴容為8,否則擴容為4。擴容完成後,將資料遷移到新的陣列中。
get方法與sparsearray差不多。
SparseArray擴容機制
sparsearray指的是稀疏陣列,就是陣列中並沒有填滿,只有部分有值,這樣造成了記憶體浪費,往往採用的是壓縮的方式來儲存內容。了解下sparsearray怎麼儲存的以及sparsearray的擴容。看下 public class sparsearrayimplements cloneable p...
稀疏sparsearray陣列
將二維陣列轉成稀疏陣列 1.先遍歷二維陣列 得到非0資料的個數 int sum 0 for int i 0 i 11 i system.out.println sum sum 建立對應的稀疏陣列 int sparsearr new int sum 1 3 給稀疏陣列賦值 sparsearr 0 0 ...
稀疏sparsearray陣列
線性結構常見的有 陣列 佇列 鍊錶和棧 非線性結構包括 二維陣列 多維陣列 廣義表 樹結構 圖結構 編寫的五子棋程式中,有存檔退出和續上盤的功能 分析問題 因為該二維陣列的很多值是預設值 0,因此記錄了很多沒有意義的資料 稀疏陣列。當乙個陣列中大部分元素為 或者為同乙個值的陣列時,可以使用稀疏陣列來...