I am trying to optimize the filter method for the RecyclerView Adapter in Android. The list is used as an ArrayList. I saw this post , but every time they are filtered from the original list.
Example: if there are 10 results for String 'a', then the user type is 'm', the results of 'am' are a subset of the results of 'a' (results.size () <= 10).
I have three questions to ask in this question,
- Is it possible to optimize HashMap memory using ArrayMap? Should I use comma separated positions in String instead of an array of Integer objects, or any way to use an int primitive array?
- I do not get animation in this result, how to get it? (I use
notifyItemInserted
not animation yet) - How much data should be stored in the Hashmap, up to 2 characters or should it fit the size of the result list?
I would be happy to know if it is possible to do something better in this code besides these points.
In the code below, mList is used in the onBindViewHolder
method. copyList always contains all the data (no installation or deletion is performed for this).
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); } } return results; } private String getSupersetIfAvailable(Map<String, List<Integer>> mSearchMap, String s) { Set<String> set = mSearchMap.keySet(); List<String> list = new ArrayList<>(set); Collections.sort(list); Collections.reverse(list); for (String c : list) { if (s.startsWith(c)) { return c; } } return null; } 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 - (fe 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++); } } }
source share