美文网首页
RecyclerView优化:SortedList的使用

RecyclerView优化:SortedList的使用

作者: 魏树鑫 | 来源:发表于2019-06-18 20:46 被阅读0次

    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的使用

          本文链接:https://www.haomeiwen.com/subject/fzmqqctx.html