SortedList算不上优化,如果列表有排序的话,可以使用这个集合来代替,实现
SortedListAdapterCallback.compare(Item t0, Item t1)
方法,来进行排序;比较方便和高效;
原理
内部数据操作大部分使用了二分查找,例如单个数据的插入,先用二分查找找出要插入的位置,然后插入;
//找到插入的位置,注意条件left < right
private int findIndexOf(T item, T[] mData, int left, int right, int reason) {
while (left < right) {
final int middle = (left + right) / 2;
T myItem = mData[middle];
final int cmp = mCallback.compare(myItem, item);
if (cmp < 0) {
left = middle + 1;
}
//中间的item正好是顺序一致的,满足排序规则,然后开始查找确切的下标,有可能出现
//areItemsTheSame相等,但是排序是另一个字段
//例如:areItemsTheSame由name判断,compare由order判断,
//当order相同时,可能name也是重复的,需要替换掉相同item或者临近插入;
else if (cmp == 0) {
if (mCallback.areItemsTheSame(myItem, item)) {
return middle;
} else {
int exact = linearEqualitySearch(item, middle, left, right);
if (reason == INSERTION) {
return exact == INVALID_POSITION ? middle : exact;
} else {
return exact;
}
}
} else {
right = middle;
}
}
return reason == INSERTION ? left : INVALID_POSITION;
}
//先从左边一半查找,再从右边一半查找
private int linearEqualitySearch(T item, int middle, int left, int right) {
// go left
for (int next = middle - 1; next >= left; next--) {
T nextItem = mData[next];
int cmp = mCallback.compare(nextItem, item);
if (cmp != 0) {
break;
}
if (mCallback.areItemsTheSame(nextItem, item)) {
return next;
}
}
for (int next = middle + 1; next < right; next++) {
T nextItem = mData[next];
int cmp = mCallback.compare(nextItem, item);
if (cmp != 0) {
break;
}
if (mCallback.areItemsTheSame(nextItem, item)) {
return next;
}
}
return INVALID_POSITION;
网友评论