作用
Bucket 類主要用來存儲RecyclerView中的各種狀態,相當於用一個List存儲多個Boolean類型的狀態,之所以用Bucket,是因爲節省內存,使用位運算,運算效率高
我的理解
個人理解有點類似Android中Flags的用法,我們想存儲幾個狀態,用int的每個位保存一個狀態,int一共有32位,則可以存儲32個狀態,常規用法如下:
int flags;
int status_one = 1;
int status_two = 1<<1;
int status_three = 1<<2;
public void addFlags(int status){
flags | = status;
}
public void removeFlags(int status){
flags &= ~status;
}
public boolean hasFlags(int status){
return mFlags & status !=0;
}
源碼解析
- Bucket類中有一些常規的set\add\remove方法,也有一些擴展的insertXXX方法,類似以上原理
- 今天重點來說一下countOnesBefore(int index)方法
- 此方法來用來計算index以前共有多少個狀態位爲true
int countOnesBefore(int index) {
//Bucket本身是一個鏈表結構,mNext是鏈表的下一個,主要是狀態可能多餘64個(Long的位數)
if (mNext == null) {
//如果索引大於一個Bucket的容量,next也不存在,只好計算當前的數據總共有多少個狀態==true的值,這屬於安全編碼,如果調用方傳入了一個非常大的值,則返回鏈表中所有狀態的和
if (index >= BITS_PER_WORD) {
return Long.bitCount(mData);
}
//直接返回當前鏈表中狀態爲true的值(二進制中位=1的個數),末尾需要-1,參數是0,返回是0,參數是1,計算第一位,依次類推
return Long.bitCount(mData & ((1L << index) - 1));
}
if (index < BITS_PER_WORD) {
//同上
return Long.bitCount(mData & ((1L << index) - 1));
} else {
//存在next,遞歸計算next+當前值
return mNext.countOnesBefore(index - BITS_PER_WORD) + Long.bitCount(mData);
}
}