我目前正在开发一个Android应用程序,其活动包含带有aprox的RecyclerView。 1k项(数据库查看器)。用户必须能够搜索这些项目,因此我使用此过滤器实现了搜索:
class PersonFilter extends Filter
{
private PersonViewAdapter adapter;
private Person[] originalPeople;
public PersonFilter(PersonViewAdapter adapter, Person[] unfiltered)
{
super();
this.adapter = adapter;
this.originalPeople = unfiltered;
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
constraint = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
if (constraint.length() == 0)
{
results.values = originalPeople;
results.count = originalPeople.length;
}
else
{
ArrayList<Person> filtered = new ArrayList<>();
for (Person p : originalPeople)
{
//region filtering
if (p instanceof Student)
{
Student s = (Student)p;
if (s.fullName.toLowerCase().contains(constraint) ||
s.mngClass.name.contains(constraint) ||
s.getShortUsername().contains(constraint) ||
s.getLongUsername().contains(constraint))
{
filtered.add(p);
}
}
else if (p instanceof Teacher)
{
Teacher t = (Teacher)p;
if (t.fullName.toLowerCase().contains(constraint) ||
t.acronym.toLowerCase().contains(constraint) ||
t.getShortUsername().contains(constraint) ||
t.getLongUsername().contains(constraint))
{
filtered.add(p);
}
}
else
{
if (p.fullName.toLowerCase().contains(constraint) ||
p.getShortUsername().contains(constraint) ||
p.getLongUsername().contains(constraint))
{
filtered.add(p);
}
}
//endregion
}
Person[] dummy = new Person[filtered.size()];
results.values = filtered.toArray(dummy);
results.count = filtered.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
adapter.setPeople((Person[])results.values);
adapter.notifyDataSetChanged();
}
}
问题是,这样搜索效果不佳,而且我在Java / Android性能优化方面经验不足,我想知道我在这里可以改进什么。
这是'人'类(如果需要):
public abstract class Person
{
public int id;
public String fullName;
public String firstName;
public String lastName;
public String getShortUsername()
{
String ln = toUsernameForm(lastName);
String username = ln.substring(0, Math.min(ln.length(), 7)) + firstName.substring(0, 1).toLowerCase();
return username;
}
public String getLongUsername()
{
return toUsernameForm(firstName) + "." + toUsernameForm(lastName);
}
public static String toUsernameForm(String s)
{
return normalize(s.split("\\W")[0].toLowerCase().replace(" ", "")
.replace("ä", "ae")
.replace("ö", "oe")
.replace("ü", "ue")
.replace("ß", "ss"));
}
public static String normalize(String s)
{
String nfdNormalizedString = Normalizer.normalize(s, Normalizer.Form.NFD);
Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
return pattern.matcher(nfdNormalizedString).replaceAll("");
}
}
答案 0 :(得分:1)
此版本应减少类型转换。
ArrayList<Person> filtered = new ArrayList<>();
for (Person p : originalPeople)
{
//region filtering
if (p.fullName.toLowerCase().contains(constraint) ||
p.getShortUsername().contains(constraint) ||
p.getLongUsername().contains(constraint))
{
filtered.add(p);
}
else if (p instanceof Student)
{
Student s = (Student) p;
if (s.mngClass.name.contains(constraint))
{
filtered.add(p);
}
}
else if (p instanceof Teacher)
{
Teacher t = (Teacher) p;
if (t.acronym.toLowerCase().contains(constraint))
{
filtered.add(p);
}
}
//endregion
}
results.values = filtered.toArray();
results.count = filtered.size();
似乎如果长用户名包含字符序列,短版本也会这样做(可能除特殊字符外)。您可以利用这一事实来减少比较。