作用
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);
}
}