3
\$\begingroup\$

I am trying to optimize the filter method for RecyclerView Adapter in Android. The list is used as an ArrayList. I have seen this post but they are filtering from the original list every time. They are not using old results if a character is added.

Example: if there are 10 results for String 'a' then user type 'm' , 'am' results are subset of 'a' results.

Please suggest code optimizations for this method and any test-case where it fails.

public void filter(String s) {
    if (TextUtils.isEmpty(s)) {
        mList.clear();
        mList.addAll(copyList);
        notifyItemRangeRemoved(0, getItemCount());
        notifyItemRangeInserted(0, mList.size());
    } else {
        boolean isBackDirection = false;
        List<WeekWorkBean> tempList = null;
        if (s.length() < oldFilter.length()) {
            tempList = new ArrayList<>();
            tempList.addAll(mList);
            mList.clear();
            mList.addAll(copyList);
            isBackDirection = true;

        }
        for (int i = 0; i < mList.size(); i++) {
            WeekWorkBean bean = mList.get(i);
            if (!bean.getEmpName().toLowerCase().startsWith(s.toLowerCase())) {
                mList.remove(i);
                if (!isBackDirection) {
                    notifyItemRemoved(i);
                }
                i--;
            } else if (isBackDirection) {
                if (tempList.size() != 0) {
                    for (WeekWorkBean b : tempList) {
                        if (!bean.getEmpId().equals(b.getEmpId())) {
                            notifyItemInserted(i);
                        }
                    }
                } else {
                    notifyItemInserted(i);
                }
            }
        }

        oldFilter = s;
    }
}
\$\endgroup\$
0

1 Answer 1

4
+25
\$\begingroup\$

Consider using iterator instead of for-looping. That will get rid of your index manipulation (decrement if element is removed).

Iterator iterator = mList.iterator();
while(iterator.hasNext()){
   Element e = iterator.next();
   if(shouldRemove(e)){
       iterator.remove();
   }
}

Is there a performance requirement that necessitate implementation of such algorithm? In most cases, implementing conventional interfaces make code readable and modular and you'll probably benefit from performance increase should the way Android perform filtering is optimised further down the road, without doing anything.

In any case, what makes you think that this implementation is faster? Your reliance on copying ArrayLists may prove wasteful if the unfiltered list is exceptionally large.

\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.