RecyclerView优化:SortedList的使用

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;

示例

官方Demo

你可能感兴趣的:(RecyclerView优化:SortedList的使用)