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.
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.
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.
Ex.
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.
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.
Ex. 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.
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.
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
Ex. if there are 10 results for stringString 'a' then the user typestype 'm' , 'am' results are subset of 'a' results.
Please suggest code optimizations for this method and any test-case where it fails.
classpublic MyFiltervoid extendsfilter(String Filters) {
if (TextUtils.isEmpty(s)) /**{
* 1mList. check do we have search results available clear(check map has this key);
* 2mList. if available, remove all rows and add only those which are value for that key addAll(stringcopyList);
* 3. else check do we have any key available starting like this, s=harnotifyItemRangeRemoved(0, already available -ha then it can be reused
*
* @param constraint
*/
@OverridegetItemCount());
protected FilterResults performFilteringnotifyItemRangeInserted(CharSequence0, constraintmList.size() {);
} else {
//Here you have toboolean implementisBackDirection filtering= wayfalse;
final FilterResultsList<WeekWorkBean> resultstempList = new FilterResults();
null;
if (!mSearchMap.containsKey(constraints.toStringlength())) {
String supersetKey = getSupersetIfAvailable(mSearchMap,< constraintoldFilter.toStringlength());
if (supersetKey == null) {
List<Integer> foundPositionstempList = doFullSearch(copyList,new constraint.toStringArrayList<>());
mSearchMap.put(constrainttempList.toStringaddAll(), foundPositionsmList);
} else {
List<Integer> foundPositions = filterFromSuperset(copyList, mSearchMap.get(supersetKey), constraintmList.toStringclear());
mSearchMap.put(constraintmList.toStringaddAll(), foundPositionscopyList);
isBackDirection = }true;
}
//logic to filtering
for (int results.valuesi = mSearchMap;
0; results.counti =< mSearchMapmList.size();
return results;
}
private List<Integer> filterFromSuperset(List<WeekWorkBean> list, List<Integer> supersetResults, String si++) {
List<Integer> results = new ArrayList<>();
StringWeekWorkBean lowerSbean = smList.toLowerCase();
for get(int i = 0; i < supersetResults.size(); i++) {
if (list.get(supersetResults.get(i))!bean.getEmpName().toLowerCase().startsWith(lowerSs.toLowerCase())) {
results.add(supersetResultsmList.getremove(i));
}
if (!isBackDirection) {
}
return results;notifyItemRemoved(i);
}
private List<Integer> doFullSearch(List<WeekWorkBean> list, String s) {}
List<Integer> results = new ArrayList<>()i--;
for (int i = 0;} ielse <if list.size(); i++isBackDirection) {
if (list.get(i).getEmpName().toLowerCase().startsWith(stempList.toLowerCasesize()) != 0) {
results.add(i);
for (WeekWorkBean b : tempList) }{
}
returnif results;
(!bean.getEmpId().equals(b.getEmpId())) {
}
@Override
protected void publishResults(CharSequence constraint, FilterResults resultsnotifyItemInserted(i) {;
// here you can use result - (f.e. set in in adapter list)}
mList.clear();
notifyDataSetChanged();}
List<Integer> res = mSearchMap.get(constraint.toString());
} else {
int j = 0;
for notifyItemInserted(Integer i : res) {;
mList.add(copyList.get(i));}
notifyItemInserted(j++);}
}
}oldFilter = s;
}
}
The algorithm works for me, but I am concerned about memory. Can I optimize memory in these areas or others?
- I am using two lists, and as far as I know, objects of the same list only contain references of those objects. So, if the original list has 100000 elements (100000 * 8 bytes) + let filtered list
size=4000
(4000 * 8 bytes) = 832000 bytes or ~832 KB. - I have not used the
ArrayMap
class of Android. Will that save my memory by using it instead ofHashMap
, or canHashMap
memory be reduced? - What if I use
Map<String,String>
where the string value will contain a comma-separated index? Which approach is better to keep values (Integer
objects array vsString
object)?
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 the user types 'm' , 'am' results are subset of 'a' results.
Please suggest code optimizations for this method and any test-case where it fails.
class MyFilter extends Filter {
/**
* 1. check do we have search results available (check map has this key)
* 2. if available, remove all rows and add only those which are value for that key (string)
* 3. else check do we have any key available starting like this, s=har, already available -ha then it can be reused
*
* @param constraint
*/
@Override
protected FilterResults performFiltering(CharSequence constraint) {
//Here you have to implement filtering way
final FilterResults results = new FilterResults();
if (!mSearchMap.containsKey(constraint.toString())) {
String supersetKey = getSupersetIfAvailable(mSearchMap, constraint.toString());
if (supersetKey == null) {
List<Integer> foundPositions = doFullSearch(copyList, constraint.toString());
mSearchMap.put(constraint.toString(), foundPositions);
} else {
List<Integer> foundPositions = filterFromSuperset(copyList, mSearchMap.get(supersetKey), constraint.toString());
mSearchMap.put(constraint.toString(), foundPositions);
}
}
//logic to filtering
results.values = mSearchMap;
results.count = mSearchMap.size();
return results;
}
private List<Integer> filterFromSuperset(List<WeekWorkBean> list, List<Integer> supersetResults, String s) {
List<Integer> results = new ArrayList<>();
String lowerS = s.toLowerCase();
for (int i = 0; i < supersetResults.size(); i++) {
if (list.get(supersetResults.get(i)).getEmpName().toLowerCase().startsWith(lowerS)) {
results.add(supersetResults.get(i));
}
}
return results;
}
private List<Integer> doFullSearch(List<WeekWorkBean> list, String s) {
List<Integer> results = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getEmpName().toLowerCase().startsWith(s.toLowerCase())) {
results.add(i);
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// here you can use result - (f.e. set in in adapter list)
mList.clear();
notifyDataSetChanged();
List<Integer> res = mSearchMap.get(constraint.toString());
int j = 0;
for (Integer i : res) {
mList.add(copyList.get(i));
notifyItemInserted(j++);
}
}
}
The algorithm works for me, but I am concerned about memory. Can I optimize memory in these areas or others?
- I am using two lists, and as far as I know, objects of the same list only contain references of those objects. So, if the original list has 100000 elements (100000 * 8 bytes) + let filtered list
size=4000
(4000 * 8 bytes) = 832000 bytes or ~832 KB. - I have not used the
ArrayMap
class of Android. Will that save my memory by using it instead ofHashMap
, or canHashMap
memory be reduced? - What if I use
Map<String,String>
where the string value will contain a comma-separated index? Which approach is better to keep values (Integer
objects array vsString
object)?
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.
Ex. 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;
}
}