Java 用大数组表加速自动完成算法
我正在处理我的Android应用程序上的InstantSearch功能,我希望得到的结果如下图所示 除了一件事,一切都正常。我使用的ArrayList很大(它包含近40万个单词)。因此,在ListView上显示结果时会出现性能问题(滞后很多) 我很确定这是因为我的词表太长了,因为减少了它的词数,一切都很顺利 下面是我在适配器类中的筛选代码:Java 用大数组表加速自动完成算法,java,android,search,arraylist,autocomplete,Java,Android,Search,Arraylist,Autocomplete,我正在处理我的Android应用程序上的InstantSearch功能,我希望得到的结果如下图所示 除了一件事,一切都正常。我使用的ArrayList很大(它包含近40万个单词)。因此,在ListView上显示结果时会出现性能问题(滞后很多) 我很确定这是因为我的词表太长了,因为减少了它的词数,一切都很顺利 下面是我在适配器类中的筛选代码: private class SearchResultsFilter extends Filter { @Override protect
private class SearchResultsFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<String> found = new ArrayList<>();
if (constraint != null) {
for (String word : MainActivity.WordList) {
if (word.startsWith(constraint.toString().toLowerCase())) {
found.add(word);
}
}
}
filteredList = found;
filterResults.values = found;
filterResults.count = found.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
if (filterResults.count > 0) {
Log.println(Log.INFO, "Results", "FOUND");
results.clear();
results.addAll((ArrayList<String>) filterResults.values);
notifyDataSetChanged();
} else {
Log.println(Log.INFO, "Results", "-");
results.clear();
notifyDataSetInvalidated();
}
}
}
public static void loadDictionary(Activity activity) {
//loading wordslist from file.
BufferedReader line_reader = new BufferedReader(new InputStreamReader(activity.getResources().openRawResource(R.raw.wordlist)));
String line;
try {
while ((line = line_reader.readLine()) != null) {
WordList.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
Collections.sort(WordList);
谢谢大家,
祝您愉快。我是塞萨尔斯克项目的合作者,我注意到我们的问题是性能过滤方法。我们使用的单词列表中有394.000多个元素,每次用户在搜索栏的EditText中键入字母时,performFiltering方法都会检查所有元素,即使它在每次迭代中都应该排除一些。因此,我实现了一种简单的方法,将列表拆分为不同的子列表。每个列表只包含以字母表中的单个字母开头的单词 意思是:
- 列表1仅包含以字母“a”开头的单词
- 列表2仅包含以字母“b”开头的单词 等等
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Pair<String, String>> temp_list = null;
ArrayList<Pair<String, String>> found = new ArrayList<>();
if (constraint != null) {
if (!(constraint.toString().isEmpty())) {
temp_list = MainActivity.Wordlists_Map.get(constraint.toString().substring(0,1).toLowerCase());
if(temp_list != null){
for(Pair<String, String> element : temp_list){
if(element.first.startsWith(constraint.toString().toLowerCase())){
found.add(element);
}
}
}
}
}
filterResults.values = found;
filterResults.count = found.size();
return filterResults;
}
@覆盖
受保护的筛选器结果性能筛选(CharSequence约束){
FilterResults FilterResults=新的FilterResults();
ArrayList temp_list=null;
找到ArrayList=新的ArrayList();
if(约束!=null){
if(!(constraint.toString().isEmpty()){
temp_list=MainActivity.wordlist_Map.get(constraint.toString().substring(0,1.toLowerCase());
如果(临时列表!=null){
对于(成对元素:临时列表){
if(element.first.startsWith(constraint.toString().toLowerCase()){
找到。添加(元素);
}
}
}
}
}
filterResults.values=已找到;
filterResults.count=found.size();
返回过滤器结果;
}
在有人键入至少X个字母之前,不要显示自动完成。。。使用X值进行游戏,以适合您的需要needs@Selvin谢谢你的回答。我不认为这个解决方案解决了我的问题,因为每次我键入一封信时,我的代码仍然会遍历整个列表。相反,我想知道我是否可以使用不同的算法来减少每次检查的字数。也许使用不同的数据结构更好?